太平洋大西洋水流问题
给定一个 m x n 的非负整数矩阵来表示一片大陆上各个单元格的高度。"太平洋"处于大陆的左边界和上边界,而"大西洋"处于大陆的右边界和下边界。
规定水流只能按照上、下、左、右四个方向流动,且只能从高到低或者在同等高度上流动。
请找出那些水流既可以流动到"太平洋",又能流动到"大西洋"的陆地单元的坐标。
示例:
给定下面的 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]] (上图中带括号的单元).
思路
解法一:
当下一个点比当前的点大时或者等于当前点的高度时,水才能流过去。根据这个思路,找到可以流向太平洋和大西洋的点。
- 找出所有从太平洋出发的水所能达到的点;
- 找出所有从大西洋出发的水所能达到的点;
- 找出重合的点。
class Solution
{
public:
vector<vector<int>> P, A, ans;
int n, m;
vector<vector<int>> pacificAtlantic(vector<vector<int>> &heights)
{
m = heights.size();
n = heights[0].size();
P = A = vector<vector<int>>(m, vector<int>(n, 0));
for (int i = 0; i < m; ++i)
{
dfs(heights, P, i, 0);
dfs(heights, A, i, n - 1);
}
for (int j = 0; j < n; ++j)
{
dfs(heights, P, 0, j);
dfs(heights, A, m - 1, j);
}
return ans;
}
void dfs(vector<vector<int>> &heights, vector<vector<int>> &visited, int i, int j)
{
if (visited[i][j]) { // 之前访问过,忽略
return;
}
visited[i][j] = 1;
if (P[i][j] && A[i][j]) // 均可达
{
ans.push_back({i, j});
}
//上下左右深搜
if (i - 1 >= 0 && heights[i - 1][j] >= heights[i][j]) {
dfs(heights, visited, i - 1, j);
}
if (i + 1 < m && heights[i + 1][j] >= heights[i][j]) {
dfs(heights, visited, i + 1, j);
}
if (j - 1 >= 0 && heights[i][j - 1] >= heights[i][j]) {
dfs(heights, visited, i, j - 1);
}
if (j + 1 < n && heights[i][j + 1] >= heights[i][j]) {
dfs(heights, visited, i, j + 1);
}
}
};