题目
考查逆向思维,水可以向低处流,但是遍历需要重复遍历各个节点,换个角度,水可以向高处流,可以采用DFS或者BFS一次遍历即可
暴力水往低处流(剪枝优化才能AC)
class Solution {
static int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int[][] heights;
int m, n;
boolean[][] pacific;
boolean[][] atlantic;
boolean[][] visit;
public List<List<Integer>> pacificAtlantic(int[][] heights) {
this.heights = heights;
this.m = heights.length;
this.n = heights[0].length;
pacific = new boolean[m][n];
atlantic = new boolean[m][n];
visit = new boolean[m][n];
for (int i = 0; i < m; i++) {
pacific[i][0] = true;
}
for (int j = 1; j < n; j++) {
pacific[0][j] = true;
}
for (int i = 0; i < m; i++) {
atlantic[i][n - 1] = true;
}
for (int j = 0; j < n - 1; j++) {
atlantic[m - 1][j] = true;
}
List<List<Integer>> result = new ArrayList<List<Integer>>();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
dfs(i, j, i, j);
if (pacific[i][j] && atlantic[i][j]) {
List<Integer> cell = new ArrayList<Integer>();
cell.add(i);
cell.add(j);
result.add(cell);
}
}
}
return result;
}
public void dfs(int row, int col, int nextRow, int nextCol) {
if (visit[nextRow][nextCol]) {
return;
}
visit[nextRow][nextCol] = true;
if (atlantic[nextRow][nextCol]) {
atlantic[row][col] = true;
}
if (pacific[nextRow][nextCol]) {
pacific[row][col] = true;
}
if(atlantic[row][col]&&pacific[row][col]){
visit[nextRow][nextCol] = false;
return;
}
for (int[] dir : dirs) {
int newRow = nextRow + dir[0], newCol = nextCol + dir[1];
if (newRow >= 0 && newRow < m && newCol >= 0 && newCol < n
&& heights[newRow][newCol] <= heights[nextRow][nextCol]) {
dfs(row, col, newRow, newCol);
}
}
visit[nextRow][nextCol] = false;
}
}
DFS 水往高处流
class Solution {
static int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int[][] heights;
int m, n;
public List<List<Integer>> pacificAtlantic(int[][] heights) {
this.heights = heights;
this.m = heights.length;
this.n = heights[0].length;
boolean[][] pacific = new boolean[m][n];
boolean[][] atlantic = new boolean[m][n];
for (int i = 0; i < m; i++) {
dfs(i, 0, pacific);
}
for (int j = 1; j < n; j++) {
dfs(0, j, pacific);
}
for (int i = 0; i < m; i++) {
dfs(i, n - 1, atlantic);
}
for (int j = 0; j < n - 1; j++) {
dfs(m - 1, j, atlantic);
}
List<List<Integer>> result = new ArrayList<List<Integer>>();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (pacific[i][j] && atlantic[i][j]) {
List<Integer> cell = new ArrayList<Integer>();
cell.add(i);
cell.add(j);
result.add(cell);
}
}
}
return result;
}
public void dfs(int row, int col, boolean[][] ocean) {
if (ocean[row][col]) {
return;
}
ocean[row][col] = true;
for (int[] dir : dirs) {
int newRow = row + dir[0], newCol = col + dir[1];
if (newRow >= 0 && newRow < m && newCol >= 0 && newCol < n && heights[newRow][newCol] >= heights[row][col]) {
dfs(newRow, newCol, ocean);
}
}
}
}
BFS
class Solution {
static int[][] dirs = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int[][] heights;
int m, n;
public List<List<Integer>> pacificAtlantic(int[][] heights) {
this.heights = heights;
this.m = heights.length;
this.n = heights[0].length;
boolean[][] pacific = new boolean[m][n];
boolean[][] atlantic = new boolean[m][n];
for (int i = 0; i < m; i++) {
bfs(i, 0, pacific);
}
for (int j = 1; j < n; j++) {
bfs(0, j, pacific);
}
for (int i = 0; i < m; i++) {
bfs(i, n - 1, atlantic);
}
for (int j = 0; j < n - 1; j++) {
bfs(m - 1, j, atlantic);
}
List<List<Integer>> result = new ArrayList<List<Integer>>();
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (pacific[i][j] && atlantic[i][j]) {
List<Integer> cell = new ArrayList<Integer>();
cell.add(i);
cell.add(j);
result.add(cell);
}
}
}
return result;
}
public void bfs(int row, int col, boolean[][] ocean) {
if (ocean[row][col]) {
return;
}
ocean[row][col] = true;
Queue<int[]> queue = new ArrayDeque<int[]>();
queue.offer(new int[]{row, col});
while (!queue.isEmpty()) {
int[] cell = queue.poll();
for (int[] dir : dirs) {
int newRow = cell[0] + dir[0], newCol = cell[1] + dir[1];
if (newRow >= 0 && newRow < m && newCol >= 0 && newCol < n && heights[newRow][newCol] >= heights[cell[0]][cell[1]] && !ocean[newRow][newCol]) {
ocean[newRow][newCol] = true;
queue.offer(new int[]{newRow, newCol});
}
}
}
}
}