深度优先搜索(DFS)解题总结
定义
深度优先搜索算法(Depth-First-Search),是搜索算法的一种。它沿着树的深度遍历树的节点,尽可能深的搜索树的分支。
例如下图,其深度优先遍历顺序为 1->2->4->8->5->3->6->7

算法步骤
- 访问顶点v;
- 依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;
- 若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。
算法模板
# Python 递归写法
visited = set() 
def dfs(node, visited):
    if node in visited: # terminator
    	# already visited
    	return 
	visited.add(node) 
	# process current node here.
	...
	for next_node in node.children():
		if next_node not in visited:
			dfs(next_node, visited)
# 非递归写法
def DFS(self, root): 
	if tree.root is None:
		return [] 
	visited, stack = [], [root]
	while stack:
		node = stack.pop()
		visited.add(node)
		process (node)
        # 生成相关的节点
		nodes = generate_related_nodes(node)
		stack.push(nodes) 
	# other processing work
	...
// Golang 递归写法
type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}
var visited map[*TreeNode]bool = make(map[*TreeNode]bool)
func dfs(node *TreeNode, visited *map[*TreeNode]bool) {
    if _,ok:= (map[*TreeNode]bool)visited[node]; ok { // terminator
        // already visited
        return
    }
    (map[*TreeNode]bool)visited[node] = true
    // process current node here
    ...
    for _,next_node := range node.children() {
        if _,ok := (map[*TreeNode]bool)visited[next_node]; !ok{
            dfs(next_node, visited)
        }
    }
}
// 非递归写法
func DFS(root *TreeNode) {
    if root == nil {
        return
    }
    visited := make(map[*TreeNode]bool)
    stack := make([]*TreeNode, 0)
    stack = append(stack, root)
    for len(stack) > 0 {
        node = stack[len(stack)-1]
        stack = stack[:len(stack)-1]
        visited[node] = true
        process(node)
        // 生成相关的节点
        nodes = generate_related_nodes(node)
        stack.push(nodes)
    }
    // other processing work
}
要点
- 使用栈 stack
- 记录已访问节点 visited ,通常使用哈希表
适用场景
- 树
- 图
- 二维数组
实战题目
参考资料
深度优先搜索(DFS)解题总结的更多相关文章
- HDU(搜索专题) 1000 N皇后问题(深度优先搜索DFS)解题报告
		前几天一直在忙一些事情,所以一直没来得及开始这个搜索专题的训练,今天做了下这个专题的第一题,皇后问题在我没有开始接受Axie的算法低强度训练前,就早有耳闻了,但一直不知道是什么类型的题目,今天一看,原 ... 
- 深度优先搜索DFS和广度优先搜索BFS简单解析(新手向)
		深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每个点仅被访问一次,这个过程就是图的遍历.图的遍历常用的有深度优先搜索和广度优先搜索,这两者对于有向图和无向图 ... 
- 利用广度优先搜索(BFS)与深度优先搜索(DFS)实现岛屿个数的问题(java)
		需要说明一点,要成功运行本贴代码,需要重新复制我第一篇随笔<简单的循环队列>代码(版本有更新). 进入今天的主题. 今天这篇文章主要探讨广度优先搜索(BFS)结合队列和深度优先搜索(DFS ... 
- 深度优先搜索DFS和广度优先搜索BFS简单解析
		转自:https://www.cnblogs.com/FZfangzheng/p/8529132.html 深度优先搜索DFS和广度优先搜索BFS简单解析 与树的遍历类似,图的遍历要求从某一点出发,每 ... 
- 【算法入门】深度优先搜索(DFS)
		深度优先搜索(DFS) [算法入门] 1.前言深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解 ... 
- 深度优先搜索 DFS 学习笔记
		深度优先搜索 学习笔记 引入 深度优先搜索 DFS 是图论中最基础,最重要的算法之一.DFS 是一种盲目搜寻法,也就是在每个点 \(u\) 上,任选一条边 DFS,直到回溯到 \(u\) 时才选择别的 ... 
- 深度优先搜索(DFS)
		[算法入门] 郭志伟@SYSU:raphealguo(at)qq.com 2012/05/12 1.前言 深度优先搜索(缩写DFS)有点类似广度优先搜索,也是对一个连通图进行遍历的算法.它的思想是从一 ... 
- 算法总结—深度优先搜索DFS
		深度优先搜索(DFS) 往往利用递归函数实现(隐式地使用栈). 深度优先从最开始的状态出发,遍历所有可以到达的状态.由此可以对所有的状态进行操作,或列举出所有的状态. 1.poj2386 Lake C ... 
- [LeetCode OJ] Word Search      深度优先搜索DFS
		Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from l ... 
- 广度优先(bfs)和深度优先搜索(dfs)的应用实例
		广度优先搜索应用举例:计算网络跳数 图结构在解决许多网络相关的问题时直到了重要的作用. 比如,用来确定在互联网中从一个结点到另一个结点(一个网络到其他网络的网关)的最佳路径.一种建模方法是采用无向图, ... 
随机推荐
- Servlet容器启动过程
			参考:https://blog.csdn.net/fredaq/article/details/9366043 一.概念 所谓Servlet容器其实说白了是符合Servlet规范的Java web容器 ... 
- 面试题:JVM 堆内存溢出后,其他线程是否可继续工作?
			来源:http://sina.lt/gqaM 最近网上出现一个美团面试题:“一个线程OOM后,其他线程还能运行吗?”.我看网上出现了很多不靠谱的答案.这道题其实很有难度,涉及的知识点有jvm内存分配. ... 
- Python环境搭建、python项目以docker镜像方式部署到Linux
			Python环境搭建.python项目以docker镜像方式部署到Linux 本文的项目是用Python写的,记录了生成docker镜像,然后整个项目在Linux跑起来的过程: 原文链接:https: ... 
- Layui+MVC+EF (项目从新创建开始)
			最近学习Layui ,就准备通过Layui来实现之前练习的项目, 先创建一个新的Web 空项目,选MVC 新建项目 创建各种类库,模块之间添加引用,并安装必要Nuget包(EF包) 模块名称 模块 ... 
- 微信小程序通过二维码获取参数运行
			小程序开发过程中会遇到参数id会通过二维码获取,然后执行接口获取数据,但是难免会遇到带过来的参数出现乱码,这样就需要解码,多个参数时就需要进行处理取我们需要的字段值:小程序开发过程中会遇到参数id会通 ... 
- 阿里出品的最新版 Java 开发手册,嵩山版,扫地僧
			说起嵩山,我就想起乔峰,想起慕容复,以及他们两位老爹在少林寺大战的场景.当然了,最令我印象深刻的就是那位默默无闻,却一鸣惊人的扫地僧啊.这次,阿里出品的嵩山版 Java 开发手册的封面就有一个扫地僧, ... 
- C#LeetCode刷题之#350-两个数组的交集 II(Intersection of Two Arrays II)
			问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4044 访问. 给定两个数组,编写一个函数来计算它们的交集. 输入 ... 
- 利用Express+MySQL进行简单的增删改查
			前言: 随着JavaScript语言的快速发展,其功能越来越强大,能做的事情也越来越多. 目前,web前端工程师能够利用NodeJS搭建服务,也成为了越来越多互联网公司对前端开发的硬性要求. 本文主要 ... 
- 虚拟化技术之kvm管理工具virsh常用基础命令(一)
			在上一篇博客中,我们了解了KVM基础架构和部署以及图形管理工具virt-manager安装虚拟机的过程,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13499 ... 
- C++炮台实验
			炮台实验 蒜头君在玩一个战争模拟游戏,他有高度为 1,2,3,... ,n的炮台各一个,他需要把这 n个炮台从左往右排成一行,并且炮口都朝向右边. 在这个游戏中,所有炮台发射的炮弹会摧毁前方所有高度比 ... 
