go: add «2577. Minimum Time to Visit a Cell In a Grid»
URL: https://leetcode.com/problems/minimum-time-to-visit-a-cell-in-a-grid/ Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
parent
f487729a83
commit
60813e4b9a
1 changed files with 78 additions and 0 deletions
78
go/minimum-time-to-visit-a-cell-in-a-grid.go
Normal file
78
go/minimum-time-to-visit-a-cell-in-a-grid.go
Normal file
|
@ -0,0 +1,78 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
|
||||
pq "github.com/emirpasic/gods/v2/queues/priorityqueue"
|
||||
)
|
||||
|
||||
type Position struct {
|
||||
y, x int
|
||||
}
|
||||
|
||||
func (p *Position) add(v Position) Position {
|
||||
return Position{
|
||||
y: p.y + v.y,
|
||||
x: p.x + v.x,
|
||||
}
|
||||
}
|
||||
|
||||
type QueueEntry struct {
|
||||
time int
|
||||
pos Position
|
||||
}
|
||||
|
||||
func byTime(a, b QueueEntry) int {
|
||||
return cmp.Compare(a.time, b.time)
|
||||
}
|
||||
|
||||
func minimumTime(grid [][]int) int {
|
||||
if grid[0][1] > 1 && grid[1][0] > 1 {
|
||||
return -1
|
||||
}
|
||||
DIRECTIONS := []Position{
|
||||
Position{1, 0}, Position{-1, 0}, Position{0, 1}, Position{0, -1},
|
||||
}
|
||||
|
||||
rows, cols := len(grid), len(grid[0])
|
||||
visited := make([][]bool, rows)
|
||||
for i, _ := range visited {
|
||||
visited[i] = make([]bool, cols)
|
||||
}
|
||||
|
||||
valid := func(pos Position) bool {
|
||||
return pos.y >= 0 && pos.y < len(visited) &&
|
||||
pos.x >= 0 && pos.x < len(visited[pos.y]) &&
|
||||
!visited[pos.y][pos.x]
|
||||
}
|
||||
|
||||
q := pq.NewWith[QueueEntry](byTime)
|
||||
q.Enqueue(QueueEntry{grid[0][0], Position{0, 0}})
|
||||
|
||||
for current, ok := q.Dequeue(); ok; current, ok = q.Dequeue() {
|
||||
if current.pos.y == rows-1 && current.pos.x == cols-1 {
|
||||
return current.time
|
||||
}
|
||||
|
||||
if visited[current.pos.y][current.pos.x] {
|
||||
continue
|
||||
}
|
||||
visited[current.pos.y][current.pos.x] = true
|
||||
|
||||
for _, dir := range DIRECTIONS {
|
||||
next := current.pos.add(dir)
|
||||
if !valid(next) {
|
||||
continue
|
||||
}
|
||||
|
||||
waiting := 0
|
||||
if (grid[next.y][next.x]-current.time)%2 == 0 {
|
||||
waiting = 1
|
||||
}
|
||||
|
||||
q.Enqueue(QueueEntry{pos: next, time: max(grid[next.y][next.x]+waiting, current.time+1)})
|
||||
}
|
||||
}
|
||||
|
||||
return -1
|
||||
}
|
Loading…
Reference in a new issue