dfs算法模板:

1、下一层是多节点的dfs遍历

def dfs(array or root, cur_layer, path, result):
if cur_layer == len(array) or not root:
result.append(path)
return for i in range(cur_layer, len(array)):
do something with array[cur_layer:i+1] or nodes with this layer
path.append(xxx) # 修改path 或者 其他操作
dfs(array, i + 1 or cur_layer + 1, path, result)
path.pop() # 还原path 或者 还原之前的操作

不含重复元素的全排列模板,交换思路:

class Solution:
"""
@param: : A list of integers
@return: A list of unique permutations
""" def permute(self, nums):
# write your code here
result = []
self.find_permutations(nums, 0, result)
return result def find_permutations(self, nums, start_index, result):
if start_index >= len(nums):
result.append(list(nums))
return for i in range(start_index, len(nums)):
nums[start_index], nums[i] = nums[i], nums[start_index]
self.find_permutations(nums, start_index + 1, result)
nums[start_index], nums[i] = nums[i], nums[start_index]

含重复元素的全排列,交换思路,和上述代码比较无非是多了一个if判断:

class Solution:
"""
@param: : A list of integers
@return: A list of unique permutations
""" def permuteUnique(self, nums):
# write your code here
result = []
self.find_permutations(nums, 0, result)
return result def find_permutations(self, nums, start_index, result):
if start_index >= len(nums):
result.append(list(nums))
return for i in range(start_index, len(nums)):
if nums[i] in nums[start_index:i]:
continue nums[start_index], nums[i] = nums[i], nums[start_index]
self.find_permutations(nums, start_index + 1, result)
nums[start_index], nums[i] = nums[i], nums[start_index]

不含重复元素的组合算法,无脑式的先排序:

class Solution:
"""
@param nums: A set of numbers
@return: A list of lists
"""
def subsets(self, nums):
# write your code here
nums = sorted(nums)
path, result = [], []
self.dfs(nums, 0, path, result)
return result def dfs(self, nums, index, path, result):
result.append(list(path)) if index == len(nums):
return for i in range(index, len(nums)):
path.append(nums[i])
self.dfs(nums, i+1, path, result)
path.pop()

含重复元素的组合算法,无脑式的先排序,加一个if去重:

class Solution:
"""
@param nums: A set of numbers.
@return: A list of lists. All valid subsets.
"""
def subsetsWithDup(self, nums):
# write your code here
nums = sorted(nums)
path, result = [], []
self.dfs(nums, 0, path, result)
return result def dfs(self, nums, index, path, result):
result.append(list(path)) for i in range(index, len(nums)):
if i > 0 and nums[i] == nums[i-1] and i > index:
continue path.append(nums[i])
self.dfs(nums, i+1, path, result)
path.pop()

案例参考:

https://www.cnblogs.com/bonelee/p/11668685.html

https://www.cnblogs.com/bonelee/p/11667428.html

2、下一层仅2个节点的dfs,也就是二叉树的dfs

先序遍历,迭代和递归写法都要熟悉:

def preoder_traversal(root):
if not root:
return stack = [root]
while stack:
node = stack.pop()
do something with node
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
return xxx def preoder_traversal(root):
if not root:
return do something with root
preoder_traversal(root.left)
preoder_traversal(root.right)

中序遍历,迭代和递归写法:

def inoder_traversal(root):
if not root:
return stack = []
node = root
while stack or node:
if node:
stack.append(node)
node = node.left
else:
cur_node = stack.pop()
do something with cur_node
node = cur_node.right
return xxx def inoder_traversal(root):
if not root:
return inoder_traversal(root.left)
do something with root
inoder_traversal(root.right)

后序遍历,仅仅掌握递归写法:

def post_order_traversal(root):
if not root:
return post_order_traversal(root.left)
post_oder_traversal(root.right)
do something with root

遍历过程中需要记住上次遍历节点才能得到结果的,模板(中序和后序仅仅换下if else代码位置):

last_node = None
def dfs(root):
if last_node is None:
last_node = root
else:
compare(last_node, root)....
last_node = root
dfs(root.left)
dfs(root.right)

3. BST的搜索,比较简单直观,和二分类似:

            def bst_search(root, target):
if not root:
return None node = root
while node:
if node.val < target:
node = node.right
elif node.val > target:
node = node.left
else:
return node.val
return xxx

---------------------------

DFS总结:
1、第一次讲的dfs模板一定要记住。
2、二叉树的遍历,https://www.cnblogs.com/rnanprince/p/11595380.html,先序中序的递归和迭代写法必须掌握,像算法模板一样记住。后序遍历只掌握递归写法。
3、遍历过程中需要记住上次遍历节点才能得到结果的,记住模板。
last_node = None
def dfs (root):
if last_node is None:
last_node = root
else:
compare(last_node, root)....
last_node = root
dfs(root.left)
dfs(root.right)
4、BST的搜索代码要会,要记住。
5、排列组合类题目:
组合类算法,都使用分治+递归的思路去写,重复元素,先排序,无非多了一个判断。
排列类算法,用交换思路,都使用分治+递归的思路去写,重复元素,无非多了一个判断。
6、隐式图搜索:八皇后,正则表达式匹配,word拼图 i j
| |
abc ==> abc dfs(i+1, j+1)
a*bc ==> aaabc dfs(i+2, j) or dfs(i, j+1)
a.bc ==> adbc dfs(i+1, j+1) a b c
g a n
a x x
i x x
n x x
dfs(左边走)
dfs(右边走)
dfs(上边走)
dfs(下边走)
走的过程中将路径记下来 7、常见问题:
超时的处理:剪枝(cache、trie去剪枝),修改算法bfs,用dp
测试用例过不完:自己debug,放到ide去调试

DFS 算法模板的更多相关文章

  1. DFS算法(——模板习题与总结)

    首先,需要说明的是搜索算法本质上也是枚举的一种,时间复杂度还是很高的,遇到问题(特别是有水平的比赛上),不要优先使用搜索算法. 这里总结一下DFS算法: 1.从图中某个顶点出发,访问v. 2.找出刚访 ...

  2. BFS/DFS算法介绍与实现(转)

    广度优先搜索(Breadth-First-Search)和深度优先搜索(Deep-First-Search)是搜索策略中最经常用到的两种方法,特别常用于图的搜索.其中有很多的算法都用到了这两种思想,比 ...

  3. Tarjan 算法&模板

    Tarjan 算法 一.算法简介 Tarjan 算法一种由Robert Tarjan提出的求解有向图强连通分量的算法,它能做到线性时间的复杂度. 我们定义: 如果两个顶点可以相互通达,则称两个顶点强连 ...

  4. POJ 1273 Drainage Ditches(网络流dinic算法模板)

    POJ 1273给出M条边,N个点,求源点1到汇点N的最大流量. 本文主要就是附上dinic的模板,供以后参考. #include <iostream> #include <stdi ...

  5. TwoSAT算法模板

    该模板来自大白书 [解释] 给多个语句,每个语句为“ Xi为真(假) 或者 Xj为真(假)” 每个变量和拆成两个点 2*i为假, 2*i+1为真 “Xi为真 或 Xj为真”  等价于 “Xi为假 –& ...

  6. 算法模板学习专栏之总览(会慢慢陆续更新ing)

    博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/7495310.html特别不喜欢那些随便转载别人的原创文章又不给 ...

  7. POJ 1815 - Friendship - [拆点最大流求最小点割集][暴力枚举求升序割点] - [Dinic算法模板 - 邻接矩阵型]

    妖怪题目,做到现在:2017/8/19 - 1:41…… 不过想想还是值得的,至少邻接矩阵型的Dinic算法模板get√ 题目链接:http://poj.org/problem?id=1815 Tim ...

  8. HDU1532最大流 Edmonds-Karp,Dinic算法 模板

    Drainage Ditches Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...

  9. hdu 2063 过山车 (最大匹配 匈牙利算法模板)

    匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最 ...

随机推荐

  1. 安装-apache skywalking (java 应用性能监控)

    官网:http://skywalking.apache.org/ 服务器:10.30.31.28 centos 7 jdk 1.8.x ES 5.x 5.0.0-bet a2版本 . http://s ...

  2. Javascript Asynchronous Investigation

    介绍 同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务: 异步任务:不进入主线程,而进入任务队列中的任务,只有任务队列通知主线程,某个异步任务可以执行了,这个任务才会进入 ...

  3. 【Gamma】“北航社团帮”测试报告——小程序v3.0

    目录 测试计划.过程和结果 后端测试--单元测试与覆盖率 后端测试--压力测试 展示部分数据 平均数据 前端测试--小程序v3.0 新功能 各页面均可正常打开,跳转,回退 授权登录与权限检查 页面数据 ...

  4. prometheus自定义监控指标——入门

    grafana结合prometheus提供了大量的模板,虽然这些模板几乎监控到了常见的监控指标,但是有些特殊的指标还是没能提供(也可能是我没找到指标名称).受zabbix的影响,自然而然想到了自定义监 ...

  5. YYCache 的整体架构类图

  6. Vue.js 自定义组件封装实录——基于现有控件的二次封装(以计时器为例)

    在本人着手开发一个考试系统的过程中,出现了如下一个需求:制作一个倒计时的控件显示在试卷页面上.本文所记录的就是这样的一个过程. 前期工作 对于这个需求,自然我想到的是有没有现成的组件可以直接使用(本着 ...

  7. thinkphp验证码不现实多半是bom惹的祸

    thinkphp 验证码不现实多半是bom惹的祸,下面是驱除bom的代码: 链接:https://pan.baidu.com/s/1v5gm7n0L7TGyejCmQrMh2g 提取码:x2p5 免费 ...

  8. Python语言的特点及自学建议

    Python语言的特点Python语言是一种被广泛使用的高级通用脚本编程语言,具有很多区别于其他语言的特点,这里仅列出如下一些重要特点.(1)语法简洁:实现相同功能,Python语言的代码行数仅相当于 ...

  9. spring接口文档注解:@ApiOperation

    @ApiOperation不是spring自带的注解是swagger里的 com.wordnik.swagger.annotations.ApiOperation; @ApiOperation和@Ap ...

  10. 立个铁矿石的flag,从7月初开始,铁矿石的库存,可能要进入累库存阶段了.

    从发货量倒推出的到货量,用来评估未来的到货量 推测的到港量与实际北方6港到港量的关系 通过月度到港量,估计出北方6港对全国到港量的正确性. 悲观的库存预期 乐观的库存预期 大概率的情况吧