【BFS】LeetCode 417. 太平洋大西洋水流问题
题目链接
思路
问题可以转换成从四个边界出发,能和内部哪些点连通。
因为涉及到两个可达性问题,所以用两个 boolean
类型矩阵分别记录一个点到太平洋和大西洋的可达性。
代码
class Solution {
public List<List<Integer>> pacificAtlantic(int[][] heights) {
int m = heights.length;
int n = heights[0].length;
List<List<Integer>> result = new ArrayList<>();
Queue<Pair<Integer, Integer>> queueLeftUp = new LinkedList<>();
Queue<Pair<Integer, Integer>> queueRightDown = new LinkedList<>();
boolean[][] accessLeftUp = new boolean[m][n];
boolean[][] accessRightDown = new boolean[m][n];
for(int i = 0; i < m; i++){
queueLeftUp.add(new Pair<>(i, 0));
accessLeftUp[i][0] = true;
queueRightDown.add(new Pair<>(i, n - 1));
accessRightDown[i][n - 1] = true;
}
for(int i = 0; i < n; i++){
queueLeftUp.add(new Pair<>(0, i));
accessLeftUp[0][i] = true;
queueRightDown.add(new Pair<>(m - 1, i));
accessRightDown[m - 1][i] = true;
}
bfs(queueLeftUp, accessLeftUp, heights, m, n);
bfs(queueRightDown, accessRightDown, heights, m, n);
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(accessLeftUp[i][j] && accessRightDown[i][j]){
result.add(Arrays.asList(i, j));
}
}
}
return result;
}
void bfs(Queue<Pair<Integer, Integer>> queue, boolean[][] access, int[][] heights, int m, int n){
boolean[][] visited = new boolean[m][n];
while(!queue.isEmpty()){
int[] dx = new int[]{1, 0, -1, 0};
int[] dy = new int[]{0, 1, 0, -1};
int x = queue.peek().getKey();
int y = queue.remove().getValue();
int height = heights[x][y];
for(int i = 0; i < 4; i++){
int nextX = x + dx[i];
int nextY = y + dy[i];
if(valid(nextX, nextY, visited, height, heights, m, n)){
access[nextX][nextY] = true;
queue.add(new Pair<>(nextX, nextY));
visited[nextX][nextY] = true;
}
}
}
}
private boolean valid(int nextX, int nextY, boolean[][] visited, int height, int[][] heights, int m, int n) {
return (
0 <= nextX && nextX < m && 0 <= nextY && nextY < n &&
!visited[nextX][nextY] && height <= heights[nextX][nextY]
);
}
}