417 太平洋大西洋水流问题

本文最后更新于:2021年1月28日 晚上

给定一个 m x n 的非负整数矩阵来表示一片大陆上各个单元格的高度。“太平洋”处于大陆的左边界和上边界,而“大西洋”处于大陆的右边界和下边界。

规定水流只能按照上、下、左、右四个方向流动,且只能从高到低或者在同等高度上流动。

请找出那些水流既可以流动到“太平洋”,又能流动到“大西洋”的陆地单元的坐标。

提示:

  1. 输出坐标的顺序不重要
  2. mn 都小于150

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
给定下面的 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]] (上图中带括号的单元).

Solution

参考 @da-li-wang

  • 广度优先搜索
  • 构建一个状态矩阵:用第一个bit存储太平洋是否能达到此点;用第二个bit存储大西洋是否能达到此点。
  • 最终查询点状态为3(二进制为11)的点即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// @lc code=start
class Solution {
private:
int d[4][2] = {{-1,0}, {1,0}, {0,-1}, {0,1}};
int m, n;

bool inArea(int x, int y){
return x>=0 && x<m && y>=0 && y<n;
}

public:
vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) {
vector<vector<int>> res;
m = matrix.size();
if(m==0) return res;
n = matrix[0].size();
if(n==0) return res;

vector<vector<int>> status(m, vector<int>(n, 0));
queue<pair<int,int>> q;

for(int i=0; i<m; ++i){
q.push({i,0});
status[i][0] |= 1;
q.push({i,n-1});
status[i][n-1] |= 2;
}

for(int j=0; j<n; ++j){
q.push({0,j});
status[0][j] |= 1;
q.push({m-1,j});
status[m-1][j] |= 2;
}

while(!q.empty()){
auto pos = q.front();
q.pop();
int x = pos.first;
int y = pos.second;
for(int i=0; i<4; ++i){
int newx = x+d[i][0];
int newy = y+d[i][1];
if(inArea(newx, newy) && matrix[newx][newy] >= matrix[x][y]){
if(status[newx][newy] != status[x][y]){
status[newx][newy] |= status[x][y];
q.push({newx,newy});
}
}
}
}

for(int i=0; i<m; ++i){
for(int j=0; j<n; ++j){
if(status[i][j]==3)
res.push_back({i,j});
}
}
return res;
}
};
// @lc code=end

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!