20天速通LeetCodeday13:DFS深度优先搜素

前言

重点理解:一路向下,走到尽头再返回。的搜索顺序学会使用栈辅助以及递归两种形式实现树形,网格类结构的遍历,掌握节点访问标记的写法。

200:岛屿数量

题目要求:

给定一个二位网格grid,里面只有 '1'(陆地)和 '0'(水)

相连的陆地(上下左右)组成一个岛屿

要求:返回岛屿数量

核心思路

DFS深度优先搜索

具体流程:

  1. 遍历网格的每一个位置
  2. 遇到1;岛屿数+1
  3. 用DFS将与该陆地链接的所有相邻地区标记(将1变化为0)为访问过

代码实现

java 复制代码
class Solution {
    public int numIslands(char[][] grid) {
       int rows=grid.length;
       int cols=grid[0].length;
       int count=0;

       for(int i=0;i<rows;i++){
        for(int j=0;j<cols;j++){
            if(grid[i][j]=='1'){//找到新岛屿
                count++;
                dfs(grid,i,j);//淹掉
            }
        }
       }
       return count;
    }
    private void dfs(char[][] grid,int i,int j){
        int rows=grid.length;
        int cols=grid[0].length;

        //遇到0或者出界就直接跳过
        if(i<0||j<0||i>=rows||j>=cols||grid[i][j]=='0') return;

        grid[i][j]='0';//标记为已经访问过
        //上下左右方位继续dfs
        dfs(grid,i+1,j);
        dfs(grid,i-1,j);
        dfs(grid,i,j-1);
        dfs(grid,i,j+1);
    }
}

总结

遍历网格,每当遇到1,计数就+1,然后通过dfs算法将所有链接在一起的岛屿一块淹掉。

最终返回count

695:岛屿的最大面积

题目要求:

给定一个二位网格grid,里面只有 '1'(陆地)和 '0'(水)

相连的陆地(上下左右)组成一个岛屿

要求:返回最大岛屿的面积(岛屿包含的陆地格子数)

核心思路

DFS深度优先搜素

  1. 遍历每一个格子
  2. 遇到1;调用dfs计算该岛屿面积
  3. 在dfs中:每访问到1,面积+1;将1修改为0;四个方向继续dfs
  4. 维护最大值

代码实现

java 复制代码
class Solution {
    public int maxAreaOfIsland(int[][] grid) {
        int rows=grid.length;
        int cols=grid[0].length;
        int maxSize=0;

        for(int i=0;i<rows;i++){
            for(int j=0;j<cols;j++){
               if(grid[i][j]==1){
                int curSize=dfs(grid,i,j);
                maxSize=Math.max(curSize,maxSize);
               }
            }
        }
        return maxSize;
        
    }
    private int dfs(int[][] grid,int i,int j){
        int rows=grid.length;
        int cols=grid[0].length;

        if(i<0||j<0||i>=rows||j>=cols||grid[i][j]==0) return 0;

        grid[i][j]=0;
        int size=1;

        size+=dfs(grid,i-1,j);
        size+=dfs(grid,i+1,j);
        size+=dfs(grid,i,j+1);
        size+=dfs(grid,i,j-1);

        return size;
    }
}

总结

和上一题的区别就是需要额外记录岛屿的最大面积

通过观察:

发现变化的主要有dfs中面积的增加方式,主函数中最大值的维护方式

79:单词搜索

题目要求:给定一个 m×n 的字符网格 board,以及一个单词 word

判断 单词是否可以在网格中构成:

单词必须由相邻格子组成(上下左右,不允许斜对角)

同一个格子 不能重复使用

核心思路(DFS+递归)

遍历每一个格子

  • 如果当前格子是单词的第一个字母-开始DFS
    DFS递归
  • 递归函数参数:坐标(i,j);当前单词索引k(表示正在匹配word[k])
  • 终止条件:k==word.length即为true,越界/格子字符不匹配-false
  • 递归过程:临时标记当前格子(如 board[i][j] = '#'),避免重复使用;四个方向dfs;回溯恢复原格子字符
  • 如果任意一次dfs返回true,单词存在

代码实现

java 复制代码
class Solution {
    public boolean exist(char[][] board, String word) {
        int rows = board.length;
        int cols = board[0].length;

        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if (dfs(board, word, i, j, 0)) {
                    return true;
                }
            }
        }
        return false;
    }
    private boolean dfs(char[][] board,String word,int i,int j,int index){
        if(index==word.length())return true;//匹配成功
        if(i<0||j<0||i>=board.length||j>=board[0].length||board[i][j]!=word.charAt(index)) return false;

        char temp=board[i][j];//保存原值
        board[i][j]='#';//标记访问过

        boolean found=dfs(board, word, i-1, j, index+1)
                     || dfs(board, word, i+1, j, index+1)
                     || dfs(board, word, i, j-1, index+1)
                     || dfs(board, word, i, j+1, index+1);

        board[i][j]=temp;//回溯恢复

        return found;
    }
}

总结

都是DFS+回溯,本题的区别在于需要判断路径是否存在,返回布尔值

多了保存原值来保证回溯之前的结果

相关推荐
ComputerInBook1 小时前
数字图像处理(4版)——第 12 章——图像模式分类(上)(Rafael C.Gonzalez&Richard E. Woods)
图像处理·人工智能·算法·模式识别·图像模式分类
七牛开发者1 小时前
开源项目观察|ds4:本地 Agent 推理,不只是把模型跑起来
人工智能·redis·算法·开源
影sir1 小时前
OI Wiki--算法竞赛百科
经验分享·算法
吞下星星的少年·-·1 小时前
x*y的所有因数=x的所有因数分别乘以y的所有因数
算法
计算机安禾1 小时前
【c++面向对象编程】第7篇:static成员:属于类而不是对象的变量和函数
java·c++·算法
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题 第47题】【JVM篇】第7题:Young GC 和 Full GC 分别采用什么算法?
java·jvm·后端·算法·面试
Ulyanov1 小时前
《从质点到位姿:基于Python与PyVista的导弹制导控制全栈仿真》: 同台竞技——3-DOF与6-DOF模型的终极对决与误差分析
开发语言·python·算法·系统仿真·雷达电子对抗仿真
Hesionberger1 小时前
LeetCode98:验证二叉搜索树(多解)
java·开发语言·python·算法·leetcode·职场和发展
千寻girling1 小时前
周日那天参加的力扣周赛... —— 10号
java·javascript·c++·python·算法·leetcode·职场和发展