m x n
大陸の各単位セルの高さを表す負でない整数の行列が与えられると、 「太平洋」は行列の左端と上端に接し、「大西洋」は右端と下端に接します。
水は、セルから高さが同じまたは低いセルへの4方向(上、下、左、または右)にのみ流れることができます。
太平洋と大西洋の両方に水が流れるグリッド座標のリストを見つけます。
注意:
- 返されるグリッド座標の順序は重要ではありません。
- 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]](上記のマトリックスの括弧付きの位置)。
アイデア:2つのブール行列を使用して、水が内側に流れ、高地に流れて、どこに流れることができるかを確認して、計算を減らすことができます。同時に、最後の2つの行列が一致する場所は、両側に流れることができるオーバーラップポイントです。
class Solution {
public List<List<Integer>> pacificAtlantic(int[][] matrix) {
List<List<Integer>> lists = new ArrayList<List<Integer>>();
if(matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return lists;
}
int n = matrix.length;
int m = matrix[0].length;
boolean[][] visitp = new boolean[n][m];
boolean[][] visita = new boolean[n][m];
Queue<int[]> pqueue = new LinkedList<int[]>();
Queue<int[]> aqueue = new LinkedList<int[]>();
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(i == 0 || j == 0) {
pqueue.offer(new int[]{i, j});
visitp[i][j] = true;
}
if(i == n - 1 || j == m - 1) {
aqueue.offer(new int[]{i, j});
visita[i][j] = true;
}
}
}
bfs(pqueue, matrix, visitp);
bfs(aqueue, matrix, visita);
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(visitp[i][j] && visita[i][j]) {
List<Integer> list = new ArrayList<Integer>();
list.add(i);
list.add(j);
lists.add(list);
}
}
}
return lists;
}
private void bfs(Queue<int[]> queue, int[][] matrix, boolean[][] visited) {
int[] dx = {0,0,-1,1};
int[] dy = {-1,1,0,0};
int n = matrix.length;
int m = matrix[0].length;
while(!queue.isEmpty()) {
int[] head = queue.poll();
int headx = head[0];
int heady = head[1];
visited[headx][heady] = true;
for(int k = 0; k < 4; k++) {
int nx = headx + dx[k];
int ny = heady + dy[k];
if(0 <= nx && nx < n && 0 <= ny && ny < m
&& !visited[nx][ny] && matrix[nx][ny] >= matrix[headx][heady]) {
visited[nx][ny] = true;
queue.offer(new int[]{nx, ny});
}
}
}
}
}