417:太平洋大西洋水流问题
This commit is contained in:
parent
fbf51f35ec
commit
c4d093177a
119
src/main/java/leetcode/editor/cn/PacificAtlanticWaterFlow.java
Normal file
119
src/main/java/leetcode/editor/cn/PacificAtlanticWaterFlow.java
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
//给定一个 m x n 的非负整数矩阵来表示一片大陆上各个单元格的高度。“太平洋”处于大陆的左边界和上边界,而“大西洋”处于大陆的右边界和下边界。
|
||||||
|
//
|
||||||
|
// 规定水流只能按照上、下、左、右四个方向流动,且只能从高到低或者在同等高度上流动。
|
||||||
|
//
|
||||||
|
// 请找出那些水流既可以流动到“太平洋”,又能流动到“大西洋”的陆地单元的坐标。
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 提示:
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 输出坐标的顺序不重要
|
||||||
|
// m 和 n 都小于150
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 示例:
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//给定下面的 5x5 矩阵:
|
||||||
|
//
|
||||||
|
// 太平洋 ~ ~ ~ ~ ~
|
||||||
|
// ~ 1 2 2 3 (5) *
|
||||||
|
// ~ 3 2 3 (4) (4) *
|
||||||
|
// ~ 2 4 (5) 3 1 *
|
||||||
|
// ~ (6) (7) 1 4 5 *
|
||||||
|
// ~ (5) 1 1 2 4 *
|
||||||
|
// * * * * * 大西洋
|
||||||
|
//
|
||||||
|
//返回:
|
||||||
|
//
|
||||||
|
//[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (上图中带括号的单元).
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Related Topics 深度优先搜索 广度优先搜索 数组 矩阵
|
||||||
|
// 👍 274 👎 0
|
||||||
|
|
||||||
|
package leetcode.editor.cn;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
//417:太平洋大西洋水流问题
|
||||||
|
class PacificAtlanticWaterFlow {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
//测试代码
|
||||||
|
Solution solution = new PacificAtlanticWaterFlow().new Solution();
|
||||||
|
}
|
||||||
|
|
||||||
|
//力扣代码
|
||||||
|
//leetcode submit region begin(Prohibit modification and deletion)
|
||||||
|
class Solution {// 用来返回的返回值
|
||||||
|
private final List<List<Integer>> ans = new ArrayList<>();
|
||||||
|
// 方向转换的数组
|
||||||
|
private final int[][] dirs = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}};
|
||||||
|
// 大西洋和太平洋共享的访问数组
|
||||||
|
private boolean[][] visited = null;
|
||||||
|
|
||||||
|
public List<List<Integer>> pacificAtlantic(int[][] heights) {
|
||||||
|
int n = heights.length, m = heights[0].length;
|
||||||
|
visited = new boolean[n][m];
|
||||||
|
// temp 是用来记录当前深度优先搜索访问过的点
|
||||||
|
boolean[][] temp = new boolean[n][m];
|
||||||
|
// 首先从太平洋出发,看看都能遇到哪些点
|
||||||
|
for (int x = 0; x < n; ++x) {
|
||||||
|
for (int y = 0; y < m; ++y) {
|
||||||
|
// x == 0 || y == 0 表示要从太平洋出发需要满足的条件,flag == false 意味着是从太平洋出发的
|
||||||
|
if ((x == 0 || y == 0) && !temp[x][y]) dfs(heights, x, y, temp, n, m, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 同上,temp 是用来标记当前深度优先搜索访问到的点
|
||||||
|
temp = new boolean[n][m];
|
||||||
|
// 然后再从大西洋出发,看看能遇到哪些点,如果遇到的点 在 visited 中之前已经被标记为 true, 那么说明双方都可到达
|
||||||
|
for (int x = 0; x < n; ++x) {
|
||||||
|
for (int y = 0; y < m; ++y) {
|
||||||
|
// x == n - 1 || y == m - 1 表示从大西洋出发
|
||||||
|
if ((x == n - 1 || y == m - 1) && !temp[x][y]) dfs(heights, x, y, temp, n, m, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param x 深度优先搜索的起始点坐标 x
|
||||||
|
* @param y 起始点坐标 y
|
||||||
|
* @param temp 用来标记当前深度优先搜索已经访问过哪些点了
|
||||||
|
* @param flag 为 true 时意味着是大西洋来的,为 false 意味着是太平洋来的
|
||||||
|
*/
|
||||||
|
private void dfs(int[][] heights, int x, int y, boolean[][] temp, int n, int m, boolean flag) {
|
||||||
|
// 如果是大西洋来的,而且 太平洋已经访问过 {x, y} 了,就放到返回值中
|
||||||
|
if (flag && visited[x][y]) {
|
||||||
|
List<Integer> buf = new ArrayList<>();
|
||||||
|
buf.add(x);
|
||||||
|
buf.add(y);
|
||||||
|
ans.add(buf);
|
||||||
|
// 顺便把该点置为 false,防止重复记录
|
||||||
|
visited[x][y] = false;
|
||||||
|
}
|
||||||
|
// 如果是从太平洋来的,需要将 {x, y} 标记为已来过
|
||||||
|
if (!flag) visited[x][y] = true;
|
||||||
|
// 然后切换四个方向,逐个检查
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
int nx = x + dirs[i][0];
|
||||||
|
int ny = y + dirs[i][1];
|
||||||
|
// 检查新的坐标是否合法,以及当前深度优先搜索是否来过,最后还要满足 逆向 条件
|
||||||
|
if (nx >= 0 && nx < n && ny >= 0 && ny < m && !temp[nx][ny] && heights[nx][ny] >= heights[x][y]) {
|
||||||
|
temp[nx][ny] = true; // 然后在当前深度优先搜索中标记为已来过
|
||||||
|
dfs(heights, nx, ny, temp, n, m, flag); // 继续深度优先搜索
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//leetcode submit region end(Prohibit modification and deletion)
|
||||||
|
|
||||||
|
}
|
39
src/main/java/leetcode/editor/cn/PacificAtlanticWaterFlow.md
Normal file
39
src/main/java/leetcode/editor/cn/PacificAtlanticWaterFlow.md
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<p>给定一个 <code>m x n</code> 的非负整数矩阵来表示一片大陆上各个单元格的高度。“太平洋”处于大陆的左边界和上边界,而“大西洋”处于大陆的右边界和下边界。</p>
|
||||||
|
|
||||||
|
<p>规定水流只能按照上、下、左、右四个方向流动,且只能从高到低或者在同等高度上流动。</p>
|
||||||
|
|
||||||
|
<p>请找出那些水流既可以流动到“太平洋”,又能流动到“大西洋”的陆地单元的坐标。</p>
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
|
||||||
|
<p><strong>提示:</strong></p>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>输出坐标的顺序不重要</li>
|
||||||
|
<li><em>m</em> 和 <em>n</em> 都小于150</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
|
||||||
|
<p><strong>示例:</strong></p>
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
给定下面的 5x5 矩阵:
|
||||||
|
|
||||||
|
太平洋 ~ ~ ~ ~ ~
|
||||||
|
~ 1 2 2 3 (5) *
|
||||||
|
~ 3 2 3 (4) (4) *
|
||||||
|
~ 2 4 (5) 3 1 *
|
||||||
|
~ (6) (7) 1 4 5 *
|
||||||
|
~ (5) 1 1 2 4 *
|
||||||
|
* * * * * 大西洋
|
||||||
|
|
||||||
|
返回:
|
||||||
|
|
||||||
|
[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (上图中带括号的单元).
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p> </p>
|
||||||
|
<div><div>Related Topics</div><div><li>深度优先搜索</li><li>广度优先搜索</li><li>数组</li><li>矩阵</li></div></div>\n<div><li>👍 274</li><li>👎 0</li></div>
|
Loading…
Reference in New Issue
Block a user