问题描述

问题分析
- 该题一看便知是枚举所有可能性的题目,但一开始的思路是从每一个点进行dfs,这样的想法是实在是太死脑筋了。应该换个方向!!!
- 该题思路有点类似 LeetCode 130. Surrounded Regions , 从每条边界开始进行 DFS, 对连通区域进行染色,但该题的“连通区域”定义为下一个进行dfs的位置大于等于上一位置的数才可以。因为这样水才能从该位置流向海洋。
- 而且,一个位置若想流向太平洋,那么从上边界或者左边界dfs一定能遍历到该点,若想流向大西洋,那么从下边界和右边界进行dfs也一定能遍历到该点。所以,需要设置两个数组 ,和原二维数组同样大小,
Pacific[i][j] = true
说明该点能流向太平洋, 从上边界和左边界的每一个点根据“连通区域”的约定,进行dfs, 便能填好这个表(染色),Atlantic[i][j] = true
说明该点能流向大西洋,从下边界和右边界的每一个点进行dfs, 便能填好这个表(染色)
经验教训
代码实现
class Solution {
public List<int[]> pacificAtlantic(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) {
return new ArrayList<>();
}
int row = matrix.length;
int col = matrix[0].length;
boolean[][] Pacific = new boolean[row][col];
boolean[][] Atlantic = new boolean[row][col];
for (int j = 0; j < col; ++j) {
dfs(matrix, Pacific, Integer.MIN_VALUE, 0, j);
dfs(matrix, Atlantic, Integer.MIN_VALUE, row - 1, j);
}
for (int i = 0; i < row; ++i) {
dfs(matrix, Pacific, Integer.MIN_VALUE, i, 0);
dfs(matrix, Atlantic, Integer.MIN_VALUE, i, col - 1);
}
List<int[]> res = new ArrayList<>();
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
if (Pacific[i][j] && Atlantic[i][j]) {
res.add(new int[]{i, j});
}
}
}
return res;
}
public void dfs(int[][] matrix, boolean[][] available, int preNum, int x, int y) {
if (x < 0 || x >= matrix.length || y < 0 || y >= matrix[0].length || available[x][y] || matrix[x][y] < preNum) {
return;
}
available[x][y] = true;
dfs(matrix, available, matrix[x][y], x - 1, y);
dfs(matrix, available, matrix[x][y], x + 1, y);
dfs(matrix, available, matrix[x][y], x, y - 1);
dfs(matrix, available, matrix[x][y], x, y + 1);
return;
}
}