DFS 算法模板
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 算法模板的更多相关文章
- DFS算法(——模板习题与总结)
首先,需要说明的是搜索算法本质上也是枚举的一种,时间复杂度还是很高的,遇到问题(特别是有水平的比赛上),不要优先使用搜索算法. 这里总结一下DFS算法: 1.从图中某个顶点出发,访问v. 2.找出刚访 ...
- BFS/DFS算法介绍与实现(转)
广度优先搜索(Breadth-First-Search)和深度优先搜索(Deep-First-Search)是搜索策略中最经常用到的两种方法,特别常用于图的搜索.其中有很多的算法都用到了这两种思想,比 ...
- Tarjan 算法&模板
Tarjan 算法 一.算法简介 Tarjan 算法一种由Robert Tarjan提出的求解有向图强连通分量的算法,它能做到线性时间的复杂度. 我们定义: 如果两个顶点可以相互通达,则称两个顶点强连 ...
- POJ 1273 Drainage Ditches(网络流dinic算法模板)
POJ 1273给出M条边,N个点,求源点1到汇点N的最大流量. 本文主要就是附上dinic的模板,供以后参考. #include <iostream> #include <stdi ...
- TwoSAT算法模板
该模板来自大白书 [解释] 给多个语句,每个语句为“ Xi为真(假) 或者 Xj为真(假)” 每个变量和拆成两个点 2*i为假, 2*i+1为真 “Xi为真 或 Xj为真” 等价于 “Xi为假 –& ...
- 算法模板学习专栏之总览(会慢慢陆续更新ing)
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/7495310.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- POJ 1815 - Friendship - [拆点最大流求最小点割集][暴力枚举求升序割点] - [Dinic算法模板 - 邻接矩阵型]
妖怪题目,做到现在:2017/8/19 - 1:41…… 不过想想还是值得的,至少邻接矩阵型的Dinic算法模板get√ 题目链接:http://poj.org/problem?id=1815 Tim ...
- HDU1532最大流 Edmonds-Karp,Dinic算法 模板
Drainage Ditches Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- hdu 2063 过山车 (最大匹配 匈牙利算法模板)
匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最 ...
随机推荐
- 最新版IntelliJ IDEA2019破解方法、补丁、注册码(激活码),永久激活
最新版IntelliJ IDEA2019破解方法.补丁.注册码(激活码),永久激活 目录 1.打赏记录 2.适用版本(适用于Windows及MacOS系统) 3.下载补丁 4.JetbrainsIde ...
- java线程池源码的理解
线程池 新建线程和切换线程的开销太大了,使用线程池可以节省系统资源. 线程池的关键类:ThreadPoolExecutor. 该类中包含了大量的多线程与并发处理工具,包括ReentrantLock.A ...
- 2018-2019-2 20165313 《网络对抗技术》 Exp 9 Web安全基础
一.实验要求 本实践的目标理解常用网络攻击技术的基本原理,做不少于7个题目,共3.5分.包括(SQL,XSS,CSRF).Webgoat实践下相关实验. 二.实验问题回答 (1)SQL注入攻击原理,如 ...
- JavaScript开发小技巧
总结一些能够提高开发效率的JS技巧 1.过滤唯一值 Set类型是在ES6中新增的,它类似于数组,但是成员的值都是唯一的,没有重复的值.结合扩展运算符(...)我们可以创建一个新的数组,达到过滤原数组重 ...
- 【c# 学习笔记】c#委托是什么
法庭上律师为当事人辩护,他真正执行的是当事人的陈词,律师就相当于一个委托对象,而当事人则委托律师对象为自己辩护. c#中的委托概念也就好比律师对象,它是一个类(“委托是类类型”这个事实将在“委托本质” ...
- select列表遍历和触发事件
1.以下两种都是jquery获取select列表被选中的value.var strText=$("#select_id").find("option:selected&q ...
- StringTable
首先看这样一个面试题 // StringTable [ "a", "b" ,"ab" ] hashtable 结构,不能扩容 public ...
- Java选择结构和循环结构
1.选择结构 ①.ifif(){ } if(){}else{} if(){}else if(){}else if(){}else{} ②.switch switch (表达式) { case 常量 1 ...
- docker系列之三:docker实际应用
以Docker为基础完成持续集成.自动交付.自动部署: 原理: RD推送代码到git 仓库或者svn等代码服务器上面,git服务器就会通过hook通知jenkins. jenkine 克隆git代码到 ...
- Vue项目(vuecli3.0搭建)集成高德地图实现路线轨迹绘制
先看最后实现的效果图 高德地图api文档 https://lbs.amap.com/api/javascript-api/summary 使用 1.在index.html里面引入高德地图js文件 2. ...