1.题目
有一个 m × n 的矩形岛屿,与 太平洋 和 大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界,而 “大西洋” 处于大陆的右边界和下边界。
这个岛被分割成一个由若干方形单元格组成的网格。给定一个 m x n 的整数矩阵 heights , heights[r][c] 表示坐标 (r, c) 上单元格 高于海平面的高度 。
岛上雨水较多,如果相邻单元格的高度 小于或等于 当前单元格的高度,雨水可以直接向北、南、东、西流向相邻单元格。水可以从海洋附近的任何单元格流入海洋。
返回 网格坐标 result 的 2D列表 ,其中 result[i] = [ri, ci] 表示雨水可以从单元格 (ri, ci) 流向 太平洋和大西洋 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/pacific-atlantic-water-flow
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
输入: heights = [[2,1],[1,2]]
输出: [[0,0],[0,1],[1,0],[1,1]]
提示:
- m == heights.length
- n == heights[r].length
- 1 <= m, n <= 200
-
2.思路
模拟,通过对每个方块的水流进行模拟,在四个方向上寻找,判断是否可以流到边界。但是这样顺着寻找的话,时间复杂度会比较高,考虑水流的逆流,从四条边界反向寻找,如果当前方块没有被访问过,那么将其状态设为以访问的状态,并判断是否可以访问当前方块的相邻方块(即相邻方块的高度值是否大于当前方块高度值,大于则访问改相邻方块)。从上边界和左边界开始搜索获得的是可以流入太平洋的方块,从下边界和有边界开始搜索获得的是可以流入大西洋的方块,两种均为真则放入最后的结果中。
3.代码
static const int d[4][2] = {{-1,0}, {0,-1}, {1,0}, {0,1}};
class Solution {
public:
vector<vector<int>> heights;
void dsf(int posi, int posj, vector<vector<bool>>& ocean)
{
int m = ocean.size(), n = ocean[0].size();
if(ocean[posi][posj])
{
return;
}
ocean[posi][posj] = true;
//cout << "posi: " << posi << " posj:" << posj
for(int i = 0; i < 4; i++)
{
int newi= posi + d[i][0], newj = posj + d[i][1];
if(newi >=0 && newi<m && newj>=0 && newj < n && heights[newi][newj] >= heights[posi][posj])
dsf(newi, newj, ocean);
}
}
vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {
vector<vector<int>> ans;
this->heights = heights;
int m = heights.size(), n = heights[0].size();
vector<vector<bool>> p(m, vector<bool>(n, false));
vector<vector<bool>> a(m, vector<bool>(n, false));
for(int i = 0; i < m; i++)
{
dsf(i, 0, p);
}
for(int i = 0; i < n; i++)
{
dsf(0, i, p);
}
for(int i = 0; i < n; i++)
{
dsf(m-1, i, a);
}
for(int i = 0; i < m; i++)
{
dsf(i, n-1, a);
}
for(int i = 0; i < m; i++)
{
for(int j = 0; j < n; j++)
{
if(a[i][j] && p[i][j])
{
vector<int> cell;
cell.emplace_back(i);
cell.emplace_back(j);
ans.emplace_back(cell);
}
}
}
return ans;
}
};