Leetcode417.太平洋大西洋水流问题

文章讲解了如何使用深度优先搜索策略在给定高度矩阵的岛屿中找到同时流向太平洋和大西洋的点,涉及逆流判断和路径连通性的理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有一个 m × n 的矩形岛屿,与 太平洋 和 大西洋 相邻。 “太平洋” 处于大陆的左边界和上边界,而 “大西洋” 处于大陆的右边界和下边界。

这个岛被分割成一个由若干方形单元格组成的网格。给定一个 m x n 的整数矩阵 heights , heights[r][c] 表示坐标 (r, c) 上单元格 高于海平面的高度 。

岛上雨水较多,如果相邻单元格的高度 小于或等于 当前单元格的高度,雨水可以直接向北、南、东、西流向相邻单元格。水可以从海洋附近的任何单元格流入海洋。

返回网格坐标 result 的 2D 列表 ,其中 result[i] = [ri, ci] 表示雨水从单元格 (ri, ci) 流动 既可流向太平洋也可流向大西洋 。

示例 1:

  • 输入: heights = [[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:

  • 输入: heights = [[2,1],[1,2]]
  • 输出: [[0,0],[0,1],[1,0],[1,1]]

思路:

从太平洋和大西洋的两边开始遍历深搜,相当于每次逆流而上找从海洋到陆地的道路,然后把两条道路的公共部分标记出来,这些就是能同时到达两个两个海洋的点。

说一下我刚开始做的时候的误区:

一开始我从两边遍历的时候,想的是找到一条能直接到另一个海的路,然后两边遍历完找公共部分,这样是不对的,因为我们的目的不是让一条海水流到另一个海,而是在岛上有一个点能流向两个海,所以这个路径是不连通的,从该点开始断开。

然后就是在逆流而上处理的时候,应该是判断heights[x][y]>heights[fx][fy]无效,因为此时我们是逆着路走的,并不是海水到岛里,而是岛上的雨水流到大海中,所以这里的判断是反过来的。

class Solution {
private:
    int dx[4]={0,1,0,-1};
    int dy[4]={1,0,-1,0};
    void bfs(vector<vector<int>>& heights,vector<vector<bool>>& visit,int x,int y){
        if(visit[x][y])return;
        visit[x][y]=true;
        for(int i=0;i<4;i++){
            int fx=x+dx[i];
            int fy=y+dy[i];
            if(fx<0 || fy<0 || fx>=heights.size() || fy>=heights[0].size())continue;
            if(heights[x][y]>heights[fx][fy])continue;//这里因为是逆流而上的判断,所以之前的要大于新的
            bfs(heights,visit,fx,fy);
        }
    }
public:
    vector<vector<int>> pacificAtlantic(vector<vector<int>>& heights) {
        int n=heights.size();
        int m=heights[0].size();
        vector<vector<bool>> pacific=vector<vector<bool>>(n,vector<bool>(m,false));
        vector<vector<bool>> atlantic=vector<vector<bool>>(n,vector<bool>(m,false));
         //最上和最下       
        for(int i=0;i<m;i++){
            bfs(heights,pacific,0,i);
            bfs(heights,atlantic,n-1,i);
        }
        //最左和最右
        for(int i=0;i<n;i++){
            bfs(heights,pacific,i,0);
            bfs(heights,atlantic,i,m-1);
        }
        vector<vector<int>> ans;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(pacific[i][j]&&atlantic[i][j]){
                    ans.push_back({i,j});
                }
            }
        }
        return ans;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值