From d1eccfba1a51880bece8edba08894000591eb3e0 Mon Sep 17 00:00:00 2001 From: StriveDD Date: Tue, 14 Mar 2023 19:05:39 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A00417.=E5=A4=AA=E5=B9=B3?= =?UTF-8?q?=E6=B4=8B=E5=A4=A7=E8=A5=BF=E6=B4=8B=E6=B0=B4=E6=B5=81=E9=97=AE?= =?UTF-8?q?=E9=A2=98.md=E7=9A=84Java=E7=89=88=E6=9C=AC=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../0417.太平洋大西洋水流问题.md | 124 +++++++++++++++++- problems/1020.飞地的数量.md | 3 +- 2 files changed, 123 insertions(+), 4 deletions(-) diff --git a/problems/0417.太平洋大西洋水流问题.md b/problems/0417.太平洋大西洋水流问题.md index f936399b..0ec8ebf9 100644 --- a/problems/0417.太平洋大西洋水流问题.md +++ b/problems/0417.太平洋大西洋水流问题.md @@ -230,17 +230,137 @@ for (int j = 0; j < m; j++) { dfs (heights, pacific, 0, j); // 遍历最左列,接触太平洋 dfs (heights, atlantic, n - 1, j); // 遍历最右列,接触大西洋 } -``` +``` 那么本题整体的时间复杂度其实是: 2 * n * m + n * m ,所以最终时间复杂度为 O(n * m) 。 空间复杂度为:O(n * m) 这个就不难理解了。开了几个 n * m 的数组。 - ## 其他语言版本 +### Java + +深度优先遍历: + +```Java +class Solution { + // 四个位置 + private static final int[][] position = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; + + /** + * @param heights 题目给定的二维数组 + * @param row 当前位置的行号 + * @param col 当前位置的列号 + * @param sign 记录是哪一条河,两条河中可以一个为 0,一个为 1 + * @param visited 记录这个位置可以到哪条河 + */ + public void dfs(int[][] heights, int row, int col, int sign, boolean[][][] visited) { + for (int[] current: position) { + int curRow = row + current[0], curCol = col + current[1]; + // 越界 + if (curRow < 0 || curRow >= heights.length || curCol < 0 || curCol >= heights[0].length) + continue; + // 高度不合适或者已经被访问过了 + if (heights[curRow][curCol] < heights[row][col] || visited[curRow][curCol][sign]) continue; + visited[curRow][curCol][sign] = true; + dfs(heights, curRow, curCol, sign, visited); + } + } + + public List> pacificAtlantic(int[][] heights) { + int rowSize = heights.length, colSize = heights[0].length; + List> ans = new ArrayList<>(); + // 记录 [row, col] 位置是否可以到某条河,可以为 true,反之为 false; + // 假设太平洋的标记为 1,大西洋为 0 + boolean[][][] visited = new boolean[rowSize][colSize][2]; + for (int row = 0; row < rowSize; row++) { + visited[row][colSize - 1][0] = true; + visited[row][0][1] = true; + dfs(heights, row, colSize - 1, 0, visited); + dfs(heights, row, 0, 1, visited); + } + for (int col = 0; col < colSize; col++) { + visited[rowSize - 1][col][0] = true; + visited[0][col][1] = true; + dfs(heights, rowSize - 1, col, 0, visited); + dfs(heights, 0, col, 1, visited); + } + for (int row = 0; row < rowSize; row++) { + for (int col = 0; col < colSize; col++) { + // 如果该位置即可以到太平洋又可以到大西洋,就放入答案数组 + if (visited[row][col][0] && visited[row][col][1]) + ans.add(List.of(row, col)); + } + } + return ans; + } +} +``` + +广度优先遍历: + +```Java +class Solution { + // 四个位置 + private static final int[][] position = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}}; + + /** + * @param heights 题目给定的二维数组 + * @param queue 记录可以到达边界的节点 + * @param visited 记录这个位置可以到哪条河 + */ + public void bfs(int[][] heights, Queue queue, boolean[][][] visited) { + while (!queue.isEmpty()) { + int[] curPos = queue.poll(); + for (int[] current: position) { + int row = curPos[0] + current[0], col = curPos[1] + current[1], sign = curPos[2]; + // 越界 + if (row < 0 || row >= heights.length || col < 0 || col >= heights[0].length) continue; + // 高度不合适或者已经被访问过了 + if (heights[row][col] < heights[curPos[0]][curPos[1]] || visited[row][col][sign]) continue; + visited[row][col][sign] = true; + queue.add(new int[]{row, col, sign}); + } + } + } + + public List> pacificAtlantic(int[][] heights) { + int rowSize = heights.length, colSize = heights[0].length; + List> ans = new ArrayList<>(); + boolean[][][] visited = new boolean[rowSize][colSize][2]; + // 队列,保存的数据为 [行号, 列号, 标记] + // 假设太平洋的标记为 1,大西洋为 0 + Queue queue = new ArrayDeque<>(); + for (int row = 0; row < rowSize; row++) { + visited[row][colSize - 1][0] = true; + visited[row][0][1] = true; + queue.add(new int[]{row, colSize - 1, 0}); + queue.add(new int[]{row, 0, 1}); + } + for (int col = 0; col < colSize; col++) { + visited[rowSize - 1][col][0] = true; + visited[0][col][1] = true; + queue.add(new int[]{rowSize - 1, col, 0}); + queue.add(new int[]{0, col, 1}); + } + bfs(heights, queue, visited); + for (int row = 0; row < rowSize; row++) { + for (int col = 0; col < colSize; col++) { + // 如果该位置即可以到太平洋又可以到大西洋,就放入答案数组 + if (visited[row][col][0] && visited[row][col][1]) + ans.add(List.of(row, col)); + } + } + return ans; + } +} +``` + + +

+ diff --git a/problems/1020.飞地的数量.md b/problems/1020.飞地的数量.md index ad848e73..d244e60c 100644 --- a/problems/1020.飞地的数量.md +++ b/problems/1020.飞地的数量.md @@ -146,7 +146,7 @@ public: ``` ## 其他语言版本 -**Java**: +### Java 深度优先遍历版本: @@ -277,4 +277,3 @@ class Solution { -