From 2216826a44e68db221b4e6a7f969ef19f6892308 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Thu, 14 Mar 2024 17:48:29 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.2684 No.2684.Maximum Number of Moves in a Grid --- .../README.md | 153 ++++++++--------- .../README_EN.md | 155 ++++++++++-------- .../Solution.cpp | 30 ++-- .../Solution.go | 32 ++-- .../Solution.java | 31 ++-- .../Solution.py | 29 ++-- .../Solution.ts | 20 +++ 7 files changed, 238 insertions(+), 212 deletions(-) create mode 100644 solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.ts diff --git a/solution/2600-2699/2684.Maximum Number of Moves in a Grid/README.md b/solution/2600-2699/2684.Maximum Number of Moves in a Grid/README.md index fb84a6f13b4e3..b7ef38f0e553b 100644 --- a/solution/2600-2699/2684.Maximum Number of Moves in a Grid/README.md +++ b/solution/2600-2699/2684.Maximum Number of Moves in a Grid/README.md @@ -54,65 +54,53 @@ ### 方法一:BFS -我们定义一个队列 $q$,初始时将第一列的所有单元格 $(i, 0)$ 加入队列,同时定义一个二维数组 $dist$,其中 $dist[i][j]$ 表示到达单元格 $(i, j)$ 的最大移动次数。初始时,$dist[i][j] = 0$。 +我们定义一个队列 $q$,初始时将第一列的所有行坐标加入队列中。 -接下来,我们开始进行广度优先搜索。每次取出队首的单元格 $(i, j)$,并考虑其可以到达的下一层的单元格 $(x, y)$。如果 $x$ 和 $y$ 满足 $0 \leq x < m, 0 \leq y < n$,且 $grid[x][y] \gt grid[i][j]$,并且 $dist[x][y] \lt dist[i][j] + 1$,那么我们就可以从单元格 $(i, j)$ 移动到单元格 $(x, y)$,此时我们将 $dist[x][y]$ 更新为 $dist[i][j] + 1$,并将单元格 $(x, y)$ 加入队列 $q$ 中,然后更新答案 $ans = \max(ans, dist[x][y])$。 +接下来,我们从第一列开始,逐列进行遍历。对于每一列,我们将队列中的所有行坐标依次取出,然后对于每一个行坐标 $i$,我们得到其下一列的所有可能行坐标 $k$,并且满足 $grid[i][j] < grid[k][j + 1]$,将这些行坐标加入到一个新的集合 $t$ 中。如果 $t$ 为空,说明我们无法继续移动,返回当前列数。否则,我们将 $t$ 赋值给 $q$,继续下一列的遍历。 -当队列为空时,我们就找到了矩阵中移动的最大次数,返回 $ans$ 即可。 +最后,如果我们遍历完了所有列,说明我们可以移动到最后一列,返回 $n - 1$。 -时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。 +时间复杂度 $O(m \times n)$,空间复杂度 $O(m)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。 ```python class Solution: def maxMoves(self, grid: List[List[int]]) -> int: - dirs = ((-1, 1), (0, 1), (1, 1)) m, n = len(grid), len(grid[0]) - q = deque((i, 0) for i in range(m)) - dist = [[0] * n for _ in range(m)] - ans = 0 - while q: - i, j = q.popleft() - for a, b in dirs: - x, y = i + a, j + b - if ( - 0 <= x < m - and 0 <= y < n - and grid[x][y] > grid[i][j] - and dist[x][y] < dist[i][j] + 1 - ): - dist[x][y] = dist[i][j] + 1 - ans = max(ans, dist[x][y]) - q.append((x, y)) - return ans + q = set(range(m)) + for j in range(n - 1): + t = set() + for i in q: + for k in range(i - 1, i + 2): + if 0 <= k < m and grid[i][j] < grid[k][j + 1]: + t.add(k) + if not t: + return j + q = t + return n - 1 ``` ```java class Solution { public int maxMoves(int[][] grid) { - int[][] dirs = {{-1, 1}, {0, 1}, {1, 1}}; int m = grid.length, n = grid[0].length; - Deque q = new ArrayDeque<>(); - for (int i = 0; i < m; ++i) { - q.offer(new int[] {i, 0}); - } - int[][] dist = new int[m][n]; - int ans = 0; - while (!q.isEmpty()) { - var p = q.poll(); - int i = p[0], j = p[1]; - for (var dir : dirs) { - int x = i + dir[0], y = j + dir[1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] > grid[i][j] - && dist[x][y] < dist[i][j] + 1) { - dist[x][y] = dist[i][j] + 1; - ans = Math.max(ans, dist[x][y]); - q.offer(new int[] {x, y}); + Set q = IntStream.range(0, m).boxed().collect(Collectors.toSet()); + for (int j = 0; j < n - 1; ++j) { + Set t = new HashSet<>(); + for (int i : q) { + for (int k = i - 1; k <= i + 1; ++k) { + if (k >= 0 && k < m && grid[i][j] < grid[k][j + 1]) { + t.add(k); + } } } + if (t.isEmpty()) { + return j; + } + q = t; } - return ans; + return n - 1; } } ``` @@ -122,27 +110,25 @@ class Solution { public: int maxMoves(vector>& grid) { int m = grid.size(), n = grid[0].size(); - int dist[m][n]; - memset(dist, 0, sizeof(dist)); - int ans = 0; - queue> q; + unordered_set q, t; for (int i = 0; i < m; ++i) { - q.emplace(i, 0); + q.insert(i); } - int dirs[3][2] = {{-1, 1}, {0, 1}, {1, 1}}; - while (!q.empty()) { - auto [i, j] = q.front(); - q.pop(); - for (int k = 0; k < 3; ++k) { - int x = i + dirs[k][0], y = j + dirs[k][1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] > grid[i][j] && dist[x][y] < dist[i][j] + 1) { - dist[x][y] = dist[i][j] + 1; - ans = max(ans, dist[x][y]); - q.emplace(x, y); + for (int j = 0; j < n - 1; ++j) { + t.clear(); + for (int i : q) { + for (int k = i - 1; k <= i + 1; ++k) { + if (k >= 0 && k < m && grid[i][j] < grid[k][j + 1]) { + t.insert(k); + } } } + if (t.empty()) { + return j; + } + q.swap(t); } - return ans; + return n - 1; } }; ``` @@ -150,27 +136,48 @@ public: ```go func maxMoves(grid [][]int) (ans int) { m, n := len(grid), len(grid[0]) - dist := make([][]int, m) - q := [][2]int{} - for i := range dist { - dist[i] = make([]int, n) - q = append(q, [2]int{i, 0}) + q := map[int]bool{} + for i := range grid { + q[i] = true } - dirs := [][2]int{{-1, 1}, {0, 1}, {1, 1}} - for len(q) > 0 { - p := q[0] - q = q[1:] - i, j := p[0], p[1] - for _, dir := range dirs { - x, y := i+dir[0], j+dir[1] - if 0 <= x && x < m && 0 <= y && y < n && grid[x][y] > grid[i][j] && dist[x][y] < dist[i][j]+1 { - dist[x][y] = dist[i][j] + 1 - ans = max(ans, dist[x][y]) - q = append(q, [2]int{x, y}) + for j := 0; j < n-1; j++ { + t := map[int]bool{} + for i := range q { + for k := i - 1; k <= i+1; k++ { + if k >= 0 && k < m && grid[i][j] < grid[k][j+1] { + t[k] = true + } } } + if len(t) == 0 { + return j + } + q = t } - return + return n - 1 +} +``` + +```ts +function maxMoves(grid: number[][]): number { + const m = grid.length; + const n = grid[0].length; + let q = new Set(Array.from({ length: m }, (_, i) => i)); + for (let j = 0; j < n - 1; ++j) { + const t = new Set(); + for (const i of q) { + for (let k = i - 1; k <= i + 1; ++k) { + if (k >= 0 && k < m && grid[i][j] < grid[k][j + 1]) { + t.add(k); + } + } + } + if (t.size === 0) { + return j; + } + q = t; + } + return n - 1; } ``` diff --git a/solution/2600-2699/2684.Maximum Number of Moves in a Grid/README_EN.md b/solution/2600-2699/2684.Maximum Number of Moves in a Grid/README_EN.md index 27644fa182007..30026e277940f 100644 --- a/solution/2600-2699/2684.Maximum Number of Moves in a Grid/README_EN.md +++ b/solution/2600-2699/2684.Maximum Number of Moves in a Grid/README_EN.md @@ -50,59 +50,55 @@ It can be shown that it is the maximum number of moves that can be made. ## Solutions -### Solution 1 +### Solution 1: BFS + +We define a queue $q$, and initially add all the row coordinates of the first column to the queue. + +Next, we start from the first column and traverse column by column. For each column, we take out all the row coordinates in the queue one by one. For each row coordinate $i$, we get all possible row coordinates $k$ of the next column, and satisfy $grid[i][j] < grid[k][j + 1]$, and add these row coordinates to a new set $t$. If $t$ is empty, it means that we cannot continue to move, so we return the current column number. Otherwise, we assign $t$ to $q$ and continue to traverse the next column. + +Finally, if we have traversed all the columns, it means that we can move to the last column, so we return $n - 1$. + +The time complexity is $O(m \times n)$, and the space complexity is $O(m)$. Where $m$ and $n$ are the number of rows and columns in the matrix, respectively. ```python class Solution: def maxMoves(self, grid: List[List[int]]) -> int: - dirs = ((-1, 1), (0, 1), (1, 1)) m, n = len(grid), len(grid[0]) - q = deque((i, 0) for i in range(m)) - dist = [[0] * n for _ in range(m)] - ans = 0 - while q: - i, j = q.popleft() - for a, b in dirs: - x, y = i + a, j + b - if ( - 0 <= x < m - and 0 <= y < n - and grid[x][y] > grid[i][j] - and dist[x][y] < dist[i][j] + 1 - ): - dist[x][y] = dist[i][j] + 1 - ans = max(ans, dist[x][y]) - q.append((x, y)) - return ans + q = set(range(m)) + for j in range(n - 1): + t = set() + for i in q: + for k in range(i - 1, i + 2): + if 0 <= k < m and grid[i][j] < grid[k][j + 1]: + t.add(k) + if not t: + return j + q = t + return n - 1 ``` ```java class Solution { public int maxMoves(int[][] grid) { - int[][] dirs = {{-1, 1}, {0, 1}, {1, 1}}; int m = grid.length, n = grid[0].length; - Deque q = new ArrayDeque<>(); - for (int i = 0; i < m; ++i) { - q.offer(new int[] {i, 0}); - } - int[][] dist = new int[m][n]; - int ans = 0; - while (!q.isEmpty()) { - var p = q.poll(); - int i = p[0], j = p[1]; - for (var dir : dirs) { - int x = i + dir[0], y = j + dir[1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] > grid[i][j] - && dist[x][y] < dist[i][j] + 1) { - dist[x][y] = dist[i][j] + 1; - ans = Math.max(ans, dist[x][y]); - q.offer(new int[] {x, y}); + Set q = IntStream.range(0, m).boxed().collect(Collectors.toSet()); + for (int j = 0; j < n - 1; ++j) { + Set t = new HashSet<>(); + for (int i : q) { + for (int k = i - 1; k <= i + 1; ++k) { + if (k >= 0 && k < m && grid[i][j] < grid[k][j + 1]) { + t.add(k); + } } } + if (t.isEmpty()) { + return j; + } + q = t; } - return ans; + return n - 1; } } ``` @@ -112,27 +108,25 @@ class Solution { public: int maxMoves(vector>& grid) { int m = grid.size(), n = grid[0].size(); - int dist[m][n]; - memset(dist, 0, sizeof(dist)); - int ans = 0; - queue> q; + unordered_set q, t; for (int i = 0; i < m; ++i) { - q.emplace(i, 0); + q.insert(i); } - int dirs[3][2] = {{-1, 1}, {0, 1}, {1, 1}}; - while (!q.empty()) { - auto [i, j] = q.front(); - q.pop(); - for (int k = 0; k < 3; ++k) { - int x = i + dirs[k][0], y = j + dirs[k][1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] > grid[i][j] && dist[x][y] < dist[i][j] + 1) { - dist[x][y] = dist[i][j] + 1; - ans = max(ans, dist[x][y]); - q.emplace(x, y); + for (int j = 0; j < n - 1; ++j) { + t.clear(); + for (int i : q) { + for (int k = i - 1; k <= i + 1; ++k) { + if (k >= 0 && k < m && grid[i][j] < grid[k][j + 1]) { + t.insert(k); + } } } + if (t.empty()) { + return j; + } + q.swap(t); } - return ans; + return n - 1; } }; ``` @@ -140,27 +134,48 @@ public: ```go func maxMoves(grid [][]int) (ans int) { m, n := len(grid), len(grid[0]) - dist := make([][]int, m) - q := [][2]int{} - for i := range dist { - dist[i] = make([]int, n) - q = append(q, [2]int{i, 0}) + q := map[int]bool{} + for i := range grid { + q[i] = true } - dirs := [][2]int{{-1, 1}, {0, 1}, {1, 1}} - for len(q) > 0 { - p := q[0] - q = q[1:] - i, j := p[0], p[1] - for _, dir := range dirs { - x, y := i+dir[0], j+dir[1] - if 0 <= x && x < m && 0 <= y && y < n && grid[x][y] > grid[i][j] && dist[x][y] < dist[i][j]+1 { - dist[x][y] = dist[i][j] + 1 - ans = max(ans, dist[x][y]) - q = append(q, [2]int{x, y}) + for j := 0; j < n-1; j++ { + t := map[int]bool{} + for i := range q { + for k := i - 1; k <= i+1; k++ { + if k >= 0 && k < m && grid[i][j] < grid[k][j+1] { + t[k] = true + } } } + if len(t) == 0 { + return j + } + q = t } - return + return n - 1 +} +``` + +```ts +function maxMoves(grid: number[][]): number { + const m = grid.length; + const n = grid[0].length; + let q = new Set(Array.from({ length: m }, (_, i) => i)); + for (let j = 0; j < n - 1; ++j) { + const t = new Set(); + for (const i of q) { + for (let k = i - 1; k <= i + 1; ++k) { + if (k >= 0 && k < m && grid[i][j] < grid[k][j + 1]) { + t.add(k); + } + } + } + if (t.size === 0) { + return j; + } + q = t; + } + return n - 1; } ``` diff --git a/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.cpp b/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.cpp index ef69bce38aa39..36f982f8f8f7d 100644 --- a/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.cpp +++ b/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.cpp @@ -2,26 +2,24 @@ class Solution { public: int maxMoves(vector>& grid) { int m = grid.size(), n = grid[0].size(); - int dist[m][n]; - memset(dist, 0, sizeof(dist)); - int ans = 0; - queue> q; + unordered_set q, t; for (int i = 0; i < m; ++i) { - q.emplace(i, 0); + q.insert(i); } - int dirs[3][2] = {{-1, 1}, {0, 1}, {1, 1}}; - while (!q.empty()) { - auto [i, j] = q.front(); - q.pop(); - for (int k = 0; k < 3; ++k) { - int x = i + dirs[k][0], y = j + dirs[k][1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] > grid[i][j] && dist[x][y] < dist[i][j] + 1) { - dist[x][y] = dist[i][j] + 1; - ans = max(ans, dist[x][y]); - q.emplace(x, y); + for (int j = 0; j < n - 1; ++j) { + t.clear(); + for (int i : q) { + for (int k = i - 1; k <= i + 1; ++k) { + if (k >= 0 && k < m && grid[i][j] < grid[k][j + 1]) { + t.insert(k); + } } } + if (t.empty()) { + return j; + } + q.swap(t); } - return ans; + return n - 1; } }; \ No newline at end of file diff --git a/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.go b/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.go index 9a207dc2d0b5a..d1561c73006b6 100644 --- a/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.go +++ b/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.go @@ -1,24 +1,22 @@ func maxMoves(grid [][]int) (ans int) { m, n := len(grid), len(grid[0]) - dist := make([][]int, m) - q := [][2]int{} - for i := range dist { - dist[i] = make([]int, n) - q = append(q, [2]int{i, 0}) + q := map[int]bool{} + for i := range grid { + q[i] = true } - dirs := [][2]int{{-1, 1}, {0, 1}, {1, 1}} - for len(q) > 0 { - p := q[0] - q = q[1:] - i, j := p[0], p[1] - for _, dir := range dirs { - x, y := i+dir[0], j+dir[1] - if 0 <= x && x < m && 0 <= y && y < n && grid[x][y] > grid[i][j] && dist[x][y] < dist[i][j]+1 { - dist[x][y] = dist[i][j] + 1 - ans = max(ans, dist[x][y]) - q = append(q, [2]int{x, y}) + for j := 0; j < n-1; j++ { + t := map[int]bool{} + for i := range q { + for k := i - 1; k <= i+1; k++ { + if k >= 0 && k < m && grid[i][j] < grid[k][j+1] { + t[k] = true + } } } + if len(t) == 0 { + return j + } + q = t } - return + return n - 1 } \ No newline at end of file diff --git a/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.java b/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.java index 86b3959ced7dc..10027b992f7ff 100644 --- a/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.java +++ b/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.java @@ -1,26 +1,21 @@ class Solution { public int maxMoves(int[][] grid) { - int[][] dirs = {{-1, 1}, {0, 1}, {1, 1}}; int m = grid.length, n = grid[0].length; - Deque q = new ArrayDeque<>(); - for (int i = 0; i < m; ++i) { - q.offer(new int[] {i, 0}); - } - int[][] dist = new int[m][n]; - int ans = 0; - while (!q.isEmpty()) { - var p = q.poll(); - int i = p[0], j = p[1]; - for (var dir : dirs) { - int x = i + dir[0], y = j + dir[1]; - if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] > grid[i][j] - && dist[x][y] < dist[i][j] + 1) { - dist[x][y] = dist[i][j] + 1; - ans = Math.max(ans, dist[x][y]); - q.offer(new int[] {x, y}); + Set q = IntStream.range(0, m).boxed().collect(Collectors.toSet()); + for (int j = 0; j < n - 1; ++j) { + Set t = new HashSet<>(); + for (int i : q) { + for (int k = i - 1; k <= i + 1; ++k) { + if (k >= 0 && k < m && grid[i][j] < grid[k][j + 1]) { + t.add(k); + } } } + if (t.isEmpty()) { + return j; + } + q = t; } - return ans; + return n - 1; } } \ No newline at end of file diff --git a/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.py b/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.py index eca083e750ec8..569fb9f06d6d1 100644 --- a/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.py +++ b/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.py @@ -1,21 +1,14 @@ class Solution: def maxMoves(self, grid: List[List[int]]) -> int: - dirs = ((-1, 1), (0, 1), (1, 1)) m, n = len(grid), len(grid[0]) - q = deque((i, 0) for i in range(m)) - dist = [[0] * n for _ in range(m)] - ans = 0 - while q: - i, j = q.popleft() - for a, b in dirs: - x, y = i + a, j + b - if ( - 0 <= x < m - and 0 <= y < n - and grid[x][y] > grid[i][j] - and dist[x][y] < dist[i][j] + 1 - ): - dist[x][y] = dist[i][j] + 1 - ans = max(ans, dist[x][y]) - q.append((x, y)) - return ans + q = set(range(m)) + for j in range(n - 1): + t = set() + for i in q: + for k in range(i - 1, i + 2): + if 0 <= k < m and grid[i][j] < grid[k][j + 1]: + t.add(k) + if not t: + return j + q = t + return n - 1 diff --git a/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.ts b/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.ts new file mode 100644 index 0000000000000..04366552365e3 --- /dev/null +++ b/solution/2600-2699/2684.Maximum Number of Moves in a Grid/Solution.ts @@ -0,0 +1,20 @@ +function maxMoves(grid: number[][]): number { + const m = grid.length; + const n = grid[0].length; + let q = new Set(Array.from({ length: m }, (_, i) => i)); + for (let j = 0; j < n - 1; ++j) { + const t = new Set(); + for (const i of q) { + for (let k = i - 1; k <= i + 1; ++k) { + if (k >= 0 && k < m && grid[i][j] < grid[k][j + 1]) { + t.add(k); + } + } + } + if (t.size === 0) { + return j; + } + q = t; + } + return n - 1; +}