当前位置: 首页 > article >正文

005 深度优先搜索(DFS)算法详解:图解+代码+经典例题

📌 什么是深度优先搜索?

深度优先搜索(Depth-First Search,DFS)是算法竞赛和面试中最高频的暴力搜索算法之一。其核心思想是“一条路走到黑”,从起点出发,优先探索最深的节点,直到无路可走再回溯,属于回溯算法的基石。


🌳 DFS算法思想

1. 核心流程(二叉树举例)

         A/   \B     C/ \   /D  E  FDFS遍历顺序:A → B → D → E → C → F
  • 递归本质:系统调用栈实现“先进后出”
  • 回溯条件:遇到叶子节点或访问完所有子节点后回退

2. DFS与BFS对比

特性DFSBFS
数据结构栈(递归/显式栈)队列
空间复杂度O(h)(h为树高度)O(w)(w为树宽度)
适用场景路径问题、连通块最短路径、层级遍历

🛠️ DFS实现方式

1. 递归模板(最常用)

def dfs(node, visited):if node in visited:  # 终止条件returnvisited.add(node)    # 标记已访问# 处理当前节点逻辑for neighbor in node.neighbors:  # 遍历子节点dfs(neighbor, visited)

2. 显式栈模板(避免递归溢出)

def dfs_stack(start):stack = [start]visited = set()while stack:node = stack.pop()if node not in visited:visited.add(node)# 处理当前节点for neighbor in reversed(node.neighbors):  # 保证顺序stack.append(neighbor)

🔥 DFS六大经典应用场景

1. 路径查找问题

  • 例题:113. 路径总和 II
  • 代码片段
def pathSum(root, target):res = []def dfs(node, path, sum_val):if not node: returnsum_val += node.valpath.append(node.val)if not node.left and not node.right and sum_val == target:res.append(path.copy())dfs(node.left, path, sum_val)dfs(node.right, path, sum_val)path.pop()  # 关键回溯dfs(root, [], 0)return res

2. 连通块计数

  • 例题:200. 岛屿数量
  • 技巧:沉岛法(访问过的陆地标记为’0’)

3. 排列组合问题

  • 例题:46. 全排列
  • 关键:维护used数组记录已选元素

4. 拓扑排序

  • 例题:207. 课程表
  • 重点:检测图中是否存在环

5. 棋盘类问题

  • 例题:51. N 皇后
  • 优化:对角线剪枝(row-colrow+col标识)

6. 记忆化DFS

  • 例题:329. 矩阵中的最长递增路径
  • 核心:用memo数组避免重复计算

⚠️ DFS高频易错点

  1. 忘记回溯

    path.append(node.val)  # 前进
    dfs(...)
    path.pop()            # 必须回溯!
    
  2. 未剪枝导致超时
    通过排序+条件判断跳过无效分支(例:40. 组合总和 II)

  3. 递归终止条件错误
    需明确递归到叶子节点或越界时的处理方式

  4. 修改全局变量未恢复
    在修改全局状态(如矩阵元素)后,必须在回溯时还原


🚀 DFS优化技巧

1. 剪枝策略

  • 可行性剪枝:提前排除不可能的解
    (例:17. 电话号码的字母组合中跳过空输入)

  • 最优性剪枝:当前路径已劣于已知最优解时终止
    (例:剑指 Offer 34. 二叉树中和为某一值的路径)

2. 方向向量简化代码

# 四方向遍历
directions = [(-1,0), (1,0), (0,-1), (0,1)]
for dx, dy in directions:x_new, y_new = x + dx, y + dy

3. 双向DFS

  • 适用场景:目标明确的搜索问题(如127. 单词接龙)
  • 优势:将时间复杂度从O(bd)降为O(b(d/2)),b为分支因子,d为深度

💡 学习建议

  1. 先理解再背模板:通过二叉树遍历掌握递归流程
  2. 从二维矩阵入手:岛屿类问题适合培养空间思维
  3. Debug技巧
    • 打印递归树层级
    • 使用可视化工具(如Python Tutor)
  4. 延伸学习
    • 回溯算法(DFS+剪枝)
    • 迭代加深搜索(IDDFS)
    • A*算法(启发式搜索)

📚 精选LeetCode练习题

题目难度核心考点
79. 单词搜索中等二维矩阵回溯
494. 目标和中等组合问题变形
473. 火柴拼正方形中等剪枝优化
980. 不同路径 III困难状态压缩

掌握DFS的关键在于大量练习总结回溯模式。建议每天刷2-3题,坚持两周即可显著提升对DFS的掌控力!

http://www.lryc.cn/news/2385495.html

相关文章:

  • maven快速上手
  • cplex12.9 安装教程以及下载
  • 甘特图实例 dhtmlxGantt.js
  • AMD硬件笔试面试题型解析
  • 视频剪辑 VEGAS - 配置视频片段保持原长宽比
  • 力扣 54 .螺旋矩阵
  • 四、【API 开发篇 (上)】:使用 Django REST Framework 构建项目与模块 CRUD API
  • python使用pycharm和conda 设置默认使用清华镜像
  • Prometheus+Grafana实现对服务的监控
  • ARM笔记-ARM伪指令及编程基础
  • Python入门手册:Python基础语法
  • SpringBoot-SpringBoot源码解读
  • CAD如何导出PDF?PDF如何转CAD?详细教程来了
  • python-数据可视化(大数据、数据分析、可视化图像、HTML页面)
  • el-select中自定义 两组el-option,但是key不一样,并且点击需获取当前整个项的所有属性
  • 【笔记】OpenCV的学习(未完)
  • 多模态大语言模型arxiv论文略读(八十七)
  • 《棒球百科》长寿运动排名·棒球1号位
  • Maven 项目打包时添加本地 Jar 包
  • 记录将网站从http升级https
  • 如何利用 ORM 框架有效防范 SQL 注入攻击
  • spark-shuffle 类型及其对比
  • 免费PDF工具-PDF24V9.16.0【win7专用版】
  • 游戏开发实战(二):Python复刻「崩坏星穹铁道」嗷呜嗷呜事务所---源码级解析该小游戏背后的算法与设计模式【纯原创】
  • 人工智能发展
  • 在Rockchip平台上利用FFmpeg实现硬件解码与缩放并导出Python接口
  • Flink集成资源管理器
  • 一周学会Pandas2 Python数据处理与分析-Pandas2数据合并与对比-pd.concat():轴向拼接
  • 安卓原生兼容服务器
  • 优化用户体验:拦截浏览器前进后退、刷新、关闭、路由跳转等用户行为并弹窗提示