代码随想录| 图论02●695岛屿最大面积 ●1020飞地的数量 ●130被围绕的区域 ●417太平洋大西洋水流问题

这篇具有很好参考价值的文章主要介绍了代码随想录| 图论02●695岛屿最大面积 ●1020飞地的数量 ●130被围绕的区域 ●417太平洋大西洋水流问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

#695岛屿最大面积

模板题,很快.以下两种dfs,区别是看第一个点放不放到dfs函数中处理,那么初始化的area一个是1一个是0

int dir[4][2]={0,1,0,-1,1,0,-1,0};
    void dfs(int x, int y,int n, int m, int &area,vector<vector<bool>> &v, vector<vector<int>>& grid){
       
        for(int i=0;i<4;i++){
            int nextx=x+dir[i][0];
            int nexty=y+dir[i][1];
            if(nextx<0||nextx>=n||nexty<0||nexty>=m) continue;
            if(!v[nextx][nexty] && grid[nextx][nexty]==1){
                v[nextx][nexty]=true;
                area++;
                dfs(nextx,nexty,n,m,area,v,grid);
            }
        }

    }

    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int n=grid.size();
        int m=grid[0].size();
        vector<vector<bool>> v(n,vector<bool>(m,false));
        int area;
        int max=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(!v[i][j] && grid[i][j]==1){
                    v[i][j]=true;
                    area=1;
                    dfs(i,j,n,m,area,v,grid);
                    max=std::max(max,area);
                }     
            }
        }
        return max;
    }
int dir[4][2]={0,1,0,-1,1,0,-1,0};
    void dfs(int x, int y,int n, int m, int &area,vector<vector<bool>> &v, vector<vector<int>>& grid){
        
        v[x][y]=true;
        area++;
        for(int i=0;i<4;i++){
            int nextx=x+dir[i][0];
            int nexty=y+dir[i][1];
            if(nextx<0||nextx>=n||nexty<0||nexty>=m) continue;
            if(!v[nextx][nexty] && grid[nextx][nexty]==1){
                v[nextx][nexty]=true;
                
                dfs(nextx,nexty,n,m,area,v,grid);
            }
        }

    }

    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int n=grid.size();
        int m=grid[0].size();
        vector<vector<bool>> v(n,vector<bool>(m,false));
        int area;
        int max=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(!v[i][j] && grid[i][j]==1){
                    area=0;
                    dfs(i,j,n,m,area,v,grid);
                    max=std::max(max,area);
                }     
            }
        }
        return max;
    }

 bfs:对应也有两种

int dir[4][2]={0,1,0,-1,1,0,-1,0};
    void bfs(int x, int y,int n, int m, int &area,vector<vector<bool>> &v, vector<vector<int>>& grid){
        queue<pair<int,int>> que;
        que.push({x,y});
        while(!que.empty()){
            auto cur=que.front(); que.pop();
            int curx=cur.first; 
            int cury=cur.second;
            for(int i=0;i<4;i++){
                int nextx=curx+dir[i][0];
                int nexty=cury+dir[i][1];
                if(nextx<0||nextx>=n||nexty<0||nexty>=m) continue;
                if(!v[nextx][nexty] && grid[nextx][nexty]==1){
                    v[nextx][nexty]=true;
                    area++;
                    que.push({nextx,nexty});
                }
            }
        }
    }

    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int n=grid.size();
        int m=grid[0].size();
        vector<vector<bool>> v(n,vector<bool>(m,false));
        int area;
        int max=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(!v[i][j] && grid[i][j]==1){
                    v[i][j]=true;
                    area=1;
                    bfs(i,j,n,m,area,v,grid);
                    max=std::max(max,area);
                }     
            }
        }
        return max;
    }
int dir[4][2]={0,1,0,-1,1,0,-1,0};
    void bfs(int x, int y,int n, int m, int &area,vector<vector<bool>> &v, vector<vector<int>>& grid){
        queue<pair<int,int>> que;
        que.push({x,y});
        v[x][y]=true;
        area++;
        while(!que.empty()){
            auto cur=que.front(); que.pop();
            int curx=cur.first; 
            int cury=cur.second;
            for(int i=0;i<4;i++){
                int nextx=curx+dir[i][0];
                int nexty=cury+dir[i][1];
                if(nextx<0||nextx>=n||nexty<0||nexty>=m) continue;
                if(!v[nextx][nexty] && grid[nextx][nexty]==1){
                    v[nextx][nexty]=true;
                    area++;
                    que.push({nextx,nexty});
                }
            }
        }
    }

    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int n=grid.size();
        int m=grid[0].size();
        vector<vector<bool>> v(n,vector<bool>(m,false));
        int area;
        int max=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(!v[i][j] && grid[i][j]==1){
                    //v[i][j]=true;
                    area=0;
                    bfs(i,j,n,m,area,v,grid);
                    max=std::max(max,area);
                }     
            }
        }
        return max;
    }

#1020飞地的数量

下面是自己写的dfs,过了但是很多可以改进。bfs也差不多这里就不写了 

int dir[4][2]={0,1,0,-1,1,0,-1,0};
    void dfs(int x, int y, vector<vector<int>>& grid, vector<vector<bool>> &v, int &cnt){
        for(int i=0;i<4;i++){
            int nextx=x+dir[i][0];
            int nexty=y+dir[i][1];
            if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size()) continue;
            if(!v[nextx][nexty]&&grid[nextx][nexty]==1){
                v[nextx][nexty]=true;
                cnt++;
                dfs(nextx,nexty,grid,v,cnt);
            }
        }
    }
    
    int numEnclaves(vector<vector<int>>& grid) {
        int n=grid.size();
        int m=grid[0].size();
        vector<vector<bool>> v(n,vector<bool>(m,false));
        int totalcnt=0;
        int cnt=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(grid[i][j]==1) totalcnt++;
            }
        }


        for(int j=0; j<m; j++){
            // Do something with grid[0][j]
             if(!v[0][j]&&grid[0][j]==1){
                    v[0][j]=true;
                    cnt++;
                    dfs(0,j,grid,v,cnt);
                }
        }

        for(int j=0; j<m; j++){
            // Do something with grid[n-1][j]
            if(!v[n-1][j]&&grid[n-1][j]==1){
                    v[n-1][j]=true;
                    cnt++;
                    dfs(n-1,j,grid,v,cnt);
                }
        }

        for(int i=1; i<n-1; i++){
            // Do something with grid[i][0]
            if(!v[i][0]&&grid[i][0]==1){
                    v[i][0]=true;
                    cnt++;
                    dfs(i,0,grid,v,cnt);
                }
        }

        for(int i=1; i<n-1; i++){
            // Do something with grid[i][m-1]
            if(!v[i][m-1]&&grid[i][m-1]==1){
                    v[i][m-1]=true;
                    cnt++;
                    dfs(i,m-1,grid,v,cnt);
                }
        }

        return totalcnt-cnt;

        
    }

可改进的点: 1 其实遍历四周可以四个循环合为两个 

2. 不需要维护一个visited, 直接把遍历过的可以走的陆地变成0海洋 有点巧妙

代码随想录| 图论02●695岛屿最大面积 ●1020飞地的数量 ●130被围绕的区域 ●417太平洋大西洋水流问题,代码随想录一刷,深度优先,广度优先,算法,图论

随想录: 

int dir[4][2] = {-1, 0, 0, -1, 1, 0, 0, 1}; 
    int count; // 统计符合题目要求的陆地空格数量
    void dfs(vector<vector<int>>& grid, int x, int y) {
        grid[x][y] = 0;
        count++;
        for (int i = 0; i < 4; i++) { // 向四个方向遍历
            int nextx = x + dir[i][0];
            int nexty = y + dir[i][1];
            if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue;
            if (grid[nextx][nexty] == 0) continue;

            dfs (grid, nextx, nexty);
        }
        return;
    }

public:
    int numEnclaves(vector<vector<int>>& grid) {
        int n = grid.size(), m = grid[0].size();
        // 从左侧边,和右侧边 向中间遍历
        for (int i = 0; i < n; i++) {
            if (grid[i][0] == 1) dfs(grid, i, 0);
            if (grid[i][m - 1] == 1) dfs(grid, i, m - 1);
        }
        // 从上边和下边 向中间遍历
        for (int j = 0; j < m; j++) {
            if (grid[0][j] == 1) dfs(grid, 0, j);
            if (grid[n - 1][j] == 1) dfs(grid, n - 1, j);
        }
        count = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (grid[i][j] == 1) dfs(grid, i, j);
            }
        }
        return count;
    }

#130被围绕的区域

和1020飞地是反过来的。但一开始自己想不到如何只遍历里面的。看来是做不到的,还是要靠先遍历外面。随想录思路用了第三个符号来标记(确实是三种地,内地,外地,海洋),很巧妙

想练习一下bfs,因为比dfs复杂,我总是会出小错误。bfs代码:

自己实现了25min左右吧,感觉代码确实长,东西也多,我还容易出小错误

int dir[4][2]={0,1,0,-1,1,0,-1,0};

    void bfs(int x, int y, vector<vector<char>>& board, char oldc,char newc){
        queue<pair<int,int>> que;
        que.push({x,y});
        board[x][y]=newc;
        while(!que.empty()){
            auto cur=que.front();que.pop();
            int curx=cur.first;
            int cury=cur.second;
            for(int i=0;i<4;i++){
                int nextx=curx+dir[i][0];
                int nexty=cury+dir[i][1];
                if(nextx<0||nextx>=board.size()||nexty<0||nexty>=board[0].size()) continue;
                if(board[nextx][nexty]==oldc){
                    que.push({nextx,nexty});
                    board[nextx][nexty]=newc;
                }
            }
        }
    }

    void solve(vector<vector<char>>& board) {
        int n=board.size();
        int m=board[0].size();

        //itr around land,set A
        for(int j=0;j<m;j++){
            if(board[0][j]=='O') bfs(0,j,board,'O','A');
            if(board[n-1][j]=='O') bfs(n-1,j,board,'O','A');
        }

        for(int i=1;i<n-1;i++){
            if(board[i][0]=='O') bfs(i,0,board,'O','A');
            if(board[i][m-1]=='O') bfs(i,m-1,board,'O','A');
        }

        //go through all, o to x
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(board[i][j]=='O') bfs(i,j,board,'O','X');
            }
        }

        //go through all, A to o
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(board[i][j]=='A') bfs(i,j,board,'A','O');
            }
        }
    }

出错1:忘记检查边界&continue了。记住出现runtime error很有可能就是忘记检查边界了

出错2:多个循环,相互复制,要记得改里面的i,j, char之类的!不要复制了忘记改了呜呜


#417太平洋大西洋水流问题 

有思路,写出来有问题,看了随想录调整的,就过了。弄了四十多分钟

这回基本上都是逻辑思路问题,没有模板问题:

1.我想到了是从边缘逆着流上来。我原来没想到本题是两个visited,都是true就没错。

错的:我额外弄了一个叫top的2d,每次++。但有可能都从pac溜上来的两条路都可以++:

2.我原来很疑惑怎么找到一条路的末尾,其实在这道题不用找。直接两个表都是true的点就是

3. 我没想明白为什么在主函数里,不用判断这些://if(!pac[0][j]),加了也没错但反而慢文章来源地址https://www.toymoban.com/news/detail-601145.html

int dir[4][2]={0,1,0,-1,1,0,-1,0};
    void dfs(int x, int y,vector<vector<bool>> &v,vector<vector<int>>& vec){
        
        v[x][y]=true;
        for(int i=0;i<4;i++){
            int nextx=x+dir[i][0];
            int nexty=y+dir[i][1];
            if(nextx<0||nextx>=vec.size()||nexty<0||nexty>=vec[0].size()) continue;
            if(!v[nextx][nexty] && vec[nextx][nexty]>=vec[x][y]){
                v[nextx][nexty]=true;
                dfs(nextx,nexty,v,vec);
            }
            
        }
    }

    vector<vector<int>> pacificAtlantic(vector<vector<int>>& vec) {
        int n=vec.size();
        int m=vec[0].size();
        
        vector<vector<bool>> pac(n, vector<bool>(m, false));
        vector<vector<bool>> atl(n, vector<bool>(m, false));
        vector<vector<int>> res;
        
        //left, top
        for(int j=0;j<m;j++){
            //if(!pac[0][j]) dfs(0,j,pac,vec);
            dfs(0,j,pac,vec);
        }
        for(int i=0;i<n;i++){
            //if(!pac[i][0]) dfs(i,0,pac,vec);
            dfs(i,0,pac,vec);
        }

        //right bottom
        for(int j=0;j<m;j++){
            //if(!atl[n-1][j]) dfs(n-1,j,atl,vec);
            dfs(n-1,j,atl,vec);
        }
        for(int i=0;i<n;i++){
            //if(!atl[i][m-1]) dfs(i,m-1,atl,vec);
            dfs(i,m-1,atl,vec);
        }

        //check res
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(pac[i][j]&&atl[i][j]){
                    res.push_back({i,j});
                }
            }
        }
        return res;
    }

到了这里,关于代码随想录| 图论02●695岛屿最大面积 ●1020飞地的数量 ●130被围绕的区域 ●417太平洋大西洋水流问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 代码随想录 图论

    目录 797.所有可能得路径  200.岛屿数量 695.岛屿的最大面积 1020.飞地的数量  130.被围绕的区域  417.太平洋大西洋水流问题  827.最大人工岛 127.单词接龙  841.钥匙和房间 463.岛屿的周长  797. 所有可能的路径 中等 给你一个有  n  个节点的  有向无环图(DAG) ,请你找出所有从

    2024年04月10日
    浏览(47)
  • 代码随想录(番外)图论4

    417. 太平洋大西洋水流问题 那么我们可以 反过来想,从太平洋边上的节点 逆流而上,将遍历过的节点都标记上。 从大西洋的边上节点 逆流而长,将遍历过的节点也标记上。 然后两方都标记过的节点就是既可以流太平洋也可以流大西洋的节点。 也就是说通过从两边的大洋开

    2024年04月29日
    浏览(60)
  • 代码随想录(番外)图论1

    1. 深度优先搜索理论基础 2. 所有可能的路径 3. 广度优先搜索理论基础.md https://programmercarl.com/%E5%9B%BE%E8%AE%BA%E6%B7%B1%E6%90%9C%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html 1. 深度优先搜索理论基础 总结 同理回溯算法,换汤不换药 二叉树递归讲解 (opens new window)中,给出了递归三部曲。 回溯算

    2024年04月28日
    浏览(41)
  • 代码随想录day02

    ● 力扣题目链接 ● 给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。 思路 ● 暴力排序,时间复杂度O(n + nlogn) ● 使用双指针,时间复杂度O(n) 代码 ● 力扣题目链接 ● 给定一个含有 n 个正整数的数组和一个正整

    2024年02月13日
    浏览(50)
  • 代码随想录图论并查集 第七天 | 685.冗余连接II

    代码随想录图论并查集 第七天 | 685.冗余连接II 一、685.冗余连接II 题目链接:https://leetcode.cn/problems/redundant-connection-ii/ 思路:684.冗余连接中是连通且无环的无向图可直接使用并查集模板,如果想判断集合中是否有环,且那条边构成环,只需要每次加入并查集之前先判断一下是

    2024年02月06日
    浏览(54)
  • 代码随想录Day42-图论:力扣第417m、841m、463e题

    题目链接 代码随想录文章讲解链接 方法一: 用时:1h0m58s 思路 直接找哪些点既可以到达太平洋又可以到达大西洋比较麻烦,换个角度,找到太平洋可以逆流而上到达的点,再找到大西洋可以逆流而上到达的点,两者的交集就是所需要的答案。 用两个二维数组分别记录太平洋

    2024年02月05日
    浏览(60)
  • 代码随想录27|455.分发饼干,376. 摆动序列,53. 最大子序和

    链接地址 链接地址 链接地址

    2024年02月11日
    浏览(42)
  • 代码随想录Day4 | 链表02-leetcode24、19、面试题02.07、142

    题目链接:两两交换链表中的节点 思路: 双指针p1、p2,分别指向每次需要交换的节点。交换过程为p2的next指向p1,p1的next指向p2的next, 还需要注意将p1de前一个指针指向交换后的p2以确保不断链 。 1. 空链 or 只有头结点? - 直接返回head,无需做任何修改 2. 交换需要记录前驱

    2024年02月12日
    浏览(42)
  • 代码随想录图论|130. 被围绕的区域 417太平洋大西洋水流问题

    **题目:**给你一个 m x n 的矩阵 board ,由若干字符 ‘X’ 和 ‘O’ ,找到所有被 ‘X’ 围绕的区域,并将这些区域里所有的 ‘O’ 用 ‘X’ 填充。 题目链接:130. 被围绕的区域 解题思路:在飞地的基础上做改动,使用一个栈存储需要改变的节点 题目 :有一个 m × n 的矩形岛

    2024年02月04日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包