Pacific Atlantic Water Flow
一开始没做出来,因为我的思考过程是从matrix[i][j]这个点走,能否走道pacific和atlantic的变,这样思考的话,visited数组不起作用,因为可能从另一条路visit这个点,所以就做不下去了。
看了discussion,这题不论是DFS还是BFS的做法,都是从4个边开始搜索,左边和上边代表了pacific能抵达的点,右边和下边代表了atlantic能抵达的用,用dfs/bfs来更新所有点能抵达的状态。最后搜一遍全图,把pacific和atlantic都能抵达的点加到结果中去。
BFS version,建pQueue,把左边和上边的点加到queu中去做bfs;把右边和下边的点加到queue中去做bfs。这个时候维护一个能否抵挡的二维数组的状态,如果是能抵达的点,就不要再放到queue里去了。
public class Solution {
private final int[] dx = {0, 0, -1, 1};
private final int[] dy = {-1, 1, 0, 0};
public List<int[]> pacificAtlantic(int[][] matrix) {
List<int[]> result = new ArrayList<int[]>();
if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) {
return result;
}
int m = matrix.length, n = matrix[0].length;
boolean[][] pacific = new boolean[m][n];
boolean[][] atlantic = new boolean[m][n];
Queue<int[]> pQueue = new LinkedList<int[]>();
Queue<int[]> aQueue = new LinkedList<int[]>();
for (int i = 0; i < n; i++) {
pQueue.offer(new int[]{0, i});
aQueue.offer(new int[]{m - 1, i});
pacific[0][i] = true;
atlantic[m - 1][i] = true;
}
for (int i = 0; i < m; i++) {
pQueue.offer(new int[]{i, 0});
aQueue.offer(new int[]{i, n - 1});
pacific[i][0] = true;
atlantic[i][n - 1] = true;
}
bfs(matrix, pQueue, pacific);
bfs(matrix, aQueue, atlantic);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (pacific[i][j] && atlantic[i][j]) {
result.add(new int[]{i, j});
}
}
}
return result;
}
private void bfs(int[][] matrix, Queue<int[]> queue, boolean[][] visited) {
while (!queue.isEmpty()) {
int[] p = queue.poll();
int i = p[0], j = p[1];
for (int k = 0; k < 4; k++) {
int x = i + dx[k];
int y = j + dy[k];
if (x >= 0 && x < matrix.length && y >= 0 && y < matrix[0].length && !visited[x][y] && matrix[i][j] <= matrix[x][y]) {
visited[x][y] = true;
queue.offer(new int[]{x, y});
}
}
}
}
}
DFS version,和BFS version很像,从左边和上边的每一个出发做DFS,更新能够抵达的状态。
public class Solution {
private final int[] dx = {0, 0, -1, 1};
private final int[] dy = {-1, 1, 0, 0};
public List<int[]> pacificAtlantic(int[][] matrix) {
List<int[]> result = new ArrayList<int[]>();
if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) {
return result;
}
int m = matrix.length, n = matrix[0].length;
boolean[][] pacific = new boolean[m][n];
boolean[][] atlantic = new boolean[m][n];
for (int i = 0; i < m; i++) {
dfs(matrix, pacific, i, 0, Integer.MIN_VALUE);
dfs(matrix, atlantic, i, n - 1, Integer.MIN_VALUE);
}
for (int i = 0; i < n; i++) {
dfs(matrix, pacific, 0, i, Integer.MIN_VALUE);
dfs(matrix, atlantic, m - 1, i, Integer.MIN_VALUE);
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (pacific[i][j] && atlantic[i][j]) {
result.add(new int[]{i, j});
}
}
}
return result;
}
private void dfs(int[][] matrix, boolean[][] visited, int i, int j, int height) {
if (i < 0 || i >= matrix.length || j < 0 || j >= matrix[0].length || visited[i][j] || matrix[i][j] < height) {
return;
}
visited[i][j] = true;
for (int k = 0; k < 4; k++) {
int x = i + dx[k];
int y = j + dy[k];
dfs(matrix, visited, x, y, matrix[i][j]);
}
}
}