DFS在二维矩阵中的遍历总结

岛屿问题

(200)岛屿的数量

本题是利用DFS遍历二维矩阵解决岛屿问题的基本问题,后面的岛屿问题都是基于此题的代码,在主函数中进行少量的逻辑修改。
0表示水,1表示陆地

覆盖以{i,j}开始的路地。
void DFS(vector<vector<int>>& grid,int x,int y){
 if(x<0||x>=grid.size()||y<0||y>=grid[0].size()||grid[x][y]==0) return;
 grid[x][y]=0; //将走过的路地全部修改为水,避免维护visited数组。
 DFS(grid,x-1,y);
 DFS(grid,x+1,y);
 DFS(grid,x,y+1);
 DFS(grid,x,y-1);
}
int solve(vector<vector<int>>& grid){
   int m=grid.size();
   int n=grid[0].size();
   int res=0;
   for(int i=0;i<m;i++){
    for(int j=0;j<n;j++){
        if(grid[i][j]==1){
            res++;
            DFS(grid,i,j);
         }
     }
   }
}

(695) 岛屿的最大面积

本题是在200的基础上求所有岛屿的面积,在利用DFS函数淹没岛屿的同时需要记录这个岛屿的面积。可以给DFS设置返回值,记录每次淹没岛屿的数量;

int DFS(vector<vector<int>>& grid,int x,int y){
 if(x<0||x>=grid.size()||y<0||y>=grid[0].size()||grid[x][y]==0) return;
 grid[x][y]=0; //将走过的路地全部修改为水,避免维护visited数组。
 return DFS(grid,x-1,y)+DFS(grid,x+1,y)+DFS(grid,x,y+1)+DFS(grid,x,y-1)+1;
}
int solve(vector<vector<int>>& grid){
   int m=grid.size();
   int n=grid[0].size();
   int res=0;
   int maxarea=0;
   for(int i=0;i<m;i++){
    for(int j=0;j<n;j++){
        if(grid[i][j]==1){
            res=resDFS(grid,i,j);
            maxarea=max(maxarea,res);
         }
     }
   }
}

(130)被围绕的区域

本题是利用DFS将“O”改成“X”,不包含边界的“O”。在这里用到了一个小技巧就是将边界的“O”改成第三个字符“A”(或者其他),然后按照200中的遍历去判断,当遇到“A”说明是边界,将“A”在修改为“O”,遇到“O”则修改为“X”。

 void dfs(vector<vector<char>>& board, int x, int y) {
        if (x < 0 || x >= n || y < 0 || y >= m || board[x][y] != 'O') {
            return;
        }
        board[x][y] = 'A';
        dfs(board, x + 1, y);
        dfs(board, x - 1, y);
        dfs(board, x, y + 1);
        dfs(board, x, y - 1);
    }
    void solve(vector<vector<char>>& board) {
        n = board.size();
        if (n == 0) {
            return;
        }
        m = board[0].size();
        for (int i = 0; i < n; i++) {
            dfs(board, i, 0);
            dfs(board, i, m - 1);
        }
        for (int i = 1; i < m - 1; i++) {
            dfs(board, 0, i);
            dfs(board, n - 1, i);
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (board[i][j] == 'A') {
                    board[i][j] = 'O';
                } else if (board[i][j] == 'O') {
                    board[i][j] = 'X';
                }
            }
        }
    }

(1254)统计封闭岛屿的数量

本题是在200之上,将边界的岛屿全部排除掉,剩下的就是封闭的岛屿,如何将边界的岛屿排除掉呢,就是利用DFS来修改边界的岛屿。

void DFS(vector<vector<int>>& grid,int x,int y){
 if(x<0||x>=grid.size()||y<0||y>=grid[0].size()||grid[x][y]==0) return;
 grid[x][y]=0; //将走过的路地全部修改为水,避免维护visited数组。
 DFS(grid,x-1,y);
 DFS(grid,x+1,y);
 DFS(grid,x,y+1);
 DFS(grid,x,y-1);
}
int solve(vector<vector<int>>& grid){
   int m=grid.size();
   int n=grid[0].size();
   for(int j=0;j<n;j++){
      DFS(grid,0,j);
      DFS(grid,m-1,j);
    }
    for(int i=0;i<m;i++){
      DFS(grid,i,0);
      DFS(grid,i,n-1);
    }
    int res=0;
     for(int i=0;i<m;i++){
       for(int j=0;j<n;j++){
       if(grid[i][j]==0){
        res++;
        DFS(grid,i,j);
       }
      }
    }
}

(1905)统计子岛屿

本题两个岛屿,gird1和grid2,判断grid2中有多少岛屿是grid1的子岛屿。可以这样思考,如果grid1中的一个位置为0,那么grid2对应位置的岛屿肯定不是之岛屿。

void DFS(vector<vector<int>>& grid2,int x,int y){
        if(x<0||x>=grid2.size()||y<0||y>=grid2[0].size()||grid2[x][y]==0) return;
        grid2[x][y]=0;
        DFS(grid2,x+1,y);
        DFS(grid2,x-1,y);
        DFS(grid2,x,y+1);
        DFS(grid2,x,y-1);
    }
    int countSubIslands(vector<vector<int>>& grid1, vector<vector<int>>& grid2) {
          int m=grid1.size();
          int n=grid1[0].size();
          //排除掉grid中为0,
          for(int i=0;i<m;i++){
              for(int j=0;j<n;j++){
                  if(grid1[i][j]==0&&grid2[i][j]==1)
                    DFS(grid2,i,j);
              }
          }

          int res=0;
          for(int i=0;i<m;i++){
              for(int j=0;j<n;j++){
                  if(grid2[i][j]==1)
                  {
                      res++;
                      DFS(grid2,i,j);
                  }
              }
          }
          return res;

(694)不同岛屿的数量

在本题中,需要将路径序列化,上(u)、下(d)、左(L)、右®利用字符标记,然后利用set来去重。

DFS的记忆化搜索

329. 矩阵中的最长递增路径

在DFS搜索中,将每个位置的信息保存下里,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值