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

#695岛屿最大面积

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

cpp 复制代码
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;
    }
cpp 复制代码
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:对应也有两种

cpp 复制代码
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;
    }
cpp 复制代码
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也差不多这里就不写了

cpp 复制代码
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海洋有点巧妙

随想录:

cpp 复制代码
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左右吧,感觉代码确实长,东西也多,我还容易出小错误

cpp 复制代码
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的点就是

  1. 我没想明白为什么在主函数里,不用判断这些://if(!pac[0][j]),加了也没错但反而慢
cpp 复制代码
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;
    }
相关推荐
幸运超级加倍~2 分钟前
软件设计师-上午题-16 算法(4-5分)
笔记·算法
yannan2019031310 分钟前
【算法】(Python)动态规划
python·算法·动态规划
埃菲尔铁塔_CV算法12 分钟前
人工智能图像算法:开启视觉新时代的钥匙
人工智能·算法
EasyCVR12 分钟前
EHOME视频平台EasyCVR视频融合平台使用OBS进行RTMP推流,WebRTC播放出现抖动、卡顿如何解决?
人工智能·算法·ffmpeg·音视频·webrtc·监控视频接入
linsa_pursuer13 分钟前
快乐数算法
算法·leetcode·职场和发展
小芒果_0114 分钟前
P11229 [CSP-J 2024] 小木棍
c++·算法·信息学奥赛
qq_4340859016 分钟前
Day 52 || 739. 每日温度 、 496.下一个更大元素 I 、503.下一个更大元素II
算法
Beau_Will16 分钟前
ZISUOJ 2024算法基础公选课练习一(2)
算法
XuanRanDev19 分钟前
【每日一题】LeetCode - 三数之和
数据结构·算法·leetcode·1024程序员节
gkdpjj20 分钟前
C++优选算法十 哈希表
c++·算法·散列表