diff --git a/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/1.png b/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/1.png new file mode 100644 index 000000000..31d85c6d4 Binary files /dev/null and b/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/1.png differ diff --git a/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/README.md b/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/README.md new file mode 100644 index 000000000..73a6ca156 --- /dev/null +++ b/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/README.md @@ -0,0 +1,54 @@ +# [1391. Check if There is a Valid Path in a Grid][title] + +## Description +You are given an `m x n` `grid`. Each cell of `grid` represents a street. The street of `grid[i][j]` can be: + +- `1` which means a street connecting the left cell and the right cell. +- `2` which means a street connecting the upper cell and the lower cell. +- `3` which means a street connecting the left cell and the lower cell. +- `4` which means a street connecting the right cell and the lower cell. +- `5` which means a street connecting the left cell and the upper cell. +- `6` which means a street connecting the right cell and the upper cell. + +![1](./1.png) + +You will initially start at the street of the upper-left cell `(0, 0)`. A valid path in the grid is a path that starts from the upper left cell `(0, 0)` and ends at the bottom-right cell `(m - 1, n - 1)`. **The path should only follow the streets**. + +**Notice** that you are **not allowed** to change any street. + +Return `true` if there is a valid path in the grid or `false` otherwise. + +**Example 1:** + +![e1](./e1.png) + +``` +Input: grid = [[2,4,3],[6,5,2]] +Output: true +Explanation: As shown you can start at cell (0, 0) and visit all the cells of the grid to reach (m - 1, n - 1). +``` + +**Example 2:** + +![e2](./e1.png) + +``` +Input: grid = [[1,2,1],[1,2,1]] +Output: false +Explanation: As shown you the street at cell (0, 0) is not connected with any street of any other cell and you will get stuck at cell (0, 0) +``` + +**Example 3:** + +``` +Input: grid = [[1,1,2]] +Output: false +Explanation: You will get stuck at cell (0, 1) and you cannot reach cell (0, 2). +``` + +## 结语 + +如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-algorithm][me] + +[title]: https://leetcode.com/problems/check-if-there-is-a-valid-path-in-a-grid +[me]: https://github.com/kylesliu/awesome-golang-algorithm diff --git a/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/Solution.go b/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/Solution.go index d115ccf5e..4393a4a5c 100755 --- a/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/Solution.go +++ b/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/Solution.go @@ -1,5 +1,113 @@ package Solution -func Solution(x bool) bool { - return x +var dirFn = [6]func(int, int, [][]int) [][2]int{ + func(x, y int, grid [][]int) [][2]int { + m, n := len(grid), len(grid[0]) + res := make([][2]int, 0) + + nx, ny := x, y-1 + if !(nx < 0 || nx >= m || ny < 0 || ny >= n) && (grid[nx][ny] == 1 || grid[nx][ny] == 4 || grid[nx][ny] == 6) { + res = append(res, [2]int{nx, ny}) + } + nx, ny = x, y+1 + if !(nx < 0 || nx >= m || ny < 0 || ny >= n) && (grid[nx][ny] == 1 || grid[nx][ny] == 3 || grid[nx][ny] == 5) { + res = append(res, [2]int{nx, ny}) + } + return res + }, + func(x, y int, grid [][]int) [][2]int { + m, n := len(grid), len(grid[0]) + res := make([][2]int, 0) + + nx, ny := x-1, y + if !(nx < 0 || nx >= m || ny < 0 || ny >= n) && (grid[nx][ny] == 2 || grid[nx][ny] == 3 || grid[nx][ny] == 4) { + res = append(res, [2]int{nx, ny}) + } + nx, ny = x+1, y + if !(nx < 0 || nx >= m || ny < 0 || ny >= n) && (grid[nx][ny] == 2 || grid[nx][ny] == 5 || grid[nx][ny] == 6) { + res = append(res, [2]int{nx, ny}) + } + return res + }, + func(x, y int, grid [][]int) [][2]int { + m, n := len(grid), len(grid[0]) + res := make([][2]int, 0) + + nx, ny := x, y-1 + if !(nx < 0 || nx >= m || ny < 0 || ny >= n) && (grid[nx][ny] == 1 || grid[nx][ny] == 4 || grid[nx][ny] == 6) { + res = append(res, [2]int{nx, ny}) + } + nx, ny = x+1, y + if !(nx < 0 || nx >= m || ny < 0 || ny >= n) && (grid[nx][ny] == 2 || grid[nx][ny] == 5 || grid[nx][ny] == 6) { + res = append(res, [2]int{nx, ny}) + } + return res + }, + func(x, y int, grid [][]int) [][2]int { + m, n := len(grid), len(grid[0]) + res := make([][2]int, 0) + + nx, ny := x, y+1 + if !(nx < 0 || nx >= m || ny < 0 || ny >= n) && (grid[nx][ny] == 1 || grid[nx][ny] == 3 || grid[nx][ny] == 5) { + res = append(res, [2]int{nx, ny}) + } + nx, ny = x+1, y + if !(nx < 0 || nx >= m || ny < 0 || ny >= n) && (grid[nx][ny] == 2 || grid[nx][ny] == 5 || grid[nx][ny] == 6) { + res = append(res, [2]int{nx, ny}) + } + return res + }, + func(x, y int, grid [][]int) [][2]int { + m, n := len(grid), len(grid[0]) + res := make([][2]int, 0) + + nx, ny := x, y-1 + if !(nx < 0 || nx >= m || ny < 0 || ny >= n) && (grid[nx][ny] == 1 || grid[nx][ny] == 4 || grid[nx][ny] == 6) { + res = append(res, [2]int{nx, ny}) + } + nx, ny = x-1, y + if !(nx < 0 || nx >= m || ny < 0 || ny >= n) && (grid[nx][ny] == 2 || grid[nx][ny] == 3 || grid[nx][ny] == 4) { + res = append(res, [2]int{nx, ny}) + } + return res + }, + func(x, y int, grid [][]int) [][2]int { + m, n := len(grid), len(grid[0]) + res := make([][2]int, 0) + + nx, ny := x, y+1 + if !(nx < 0 || nx >= m || ny < 0 || ny >= n) && (grid[nx][ny] == 1 || grid[nx][ny] == 3 || grid[nx][ny] == 5) { + res = append(res, [2]int{nx, ny}) + } + nx, ny = x-1, y + if !(nx < 0 || nx >= m || ny < 0 || ny >= n) && (grid[nx][ny] == 2 || grid[nx][ny] == 3 || grid[nx][ny] == 4) { + res = append(res, [2]int{nx, ny}) + } + return res + }, +} + +func Solution(grid [][]int) bool { + m, n := len(grid)-1, len(grid[0])-1 + q := [][2]int{{0, 0}} + v := make(map[[2]int]struct{}) + v[[2]int{0, 0}] = struct{}{} + for len(q) > 0 { + nq := make([][2]int, 0) + for _, pos := range q { + x, y := pos[0], pos[1] + if x == m && y == n { + return true + } + for _, next := range dirFn[grid[x][y]-1](x, y, grid) { + if _, ok := v[next]; ok { + continue + } + nq = append(nq, next) + v[next] = struct{}{} + } + } + q = nq + } + return false } diff --git a/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/Solution_test.go b/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/Solution_test.go index 14ff50eb4..cc517444d 100755 --- a/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/Solution_test.go +++ b/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/Solution_test.go @@ -10,12 +10,12 @@ func TestSolution(t *testing.T) { // 测试用例 cases := []struct { name string - inputs bool + inputs [][]int expect bool }{ - {"TestCase", true, true}, - {"TestCase", true, true}, - {"TestCase", false, false}, + {"TestCase1", [][]int{{2, 4, 3}, {6, 5, 2}}, true}, + {"TestCase2", [][]int{{1, 2, 1}, {1, 2, 1}}, false}, + {"TestCase3", [][]int{{1, 1, 2}}, false}, } // 开始测试 @@ -30,10 +30,10 @@ func TestSolution(t *testing.T) { } } -// 压力测试 +// 压力测试 func BenchmarkSolution(b *testing.B) { } -// 使用案列 +// 使用案列 func ExampleSolution() { } diff --git a/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/e1.png b/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/e1.png new file mode 100644 index 000000000..014fbcba1 Binary files /dev/null and b/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/e1.png differ diff --git a/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/e2.png b/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/e2.png new file mode 100644 index 000000000..f3855555e Binary files /dev/null and b/leetcode/1301-1400/1391.Check-if-There-is-a-Valid-Path-in-a-Grid/e2.png differ