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定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最 ...
随机推荐
- ef core 全局过滤
有些固定的条件,基本每个查询的时候需要带的条件,我们可以使用全局过滤来帮我们,这样后面的查询就不用每次都带条件了. 微软自带的:https://docs.microsoft.com/zh-cn/ef/ ...
- 文本分类(TextCNN,Keras)
数据集是网上找的,已上传至我的 Github,项目完整地址:https://github.com/cyandn/practice/tree/master/text-classification 流程: ...
- ipv4的ip字符串转化为int型
要求: 将现有一个ipv4的ip字符串(仅包含数字,点,空格), 其中数字和点之间的空格(至多一个)是合法的,比如“12 .3. 4 .62”,其他情况均为非法地址.写一个函数将ipv4地址字符串转化 ...
- 使用预编译库PREBUILT LIBRARY官方说明
使用预编译库 NDK 支持使用预编译库(同时支持静态库和共享库).此功能有以下两个主要用例: 向第三方 NDK 开发者分发您自己的库(而不分发您的源代码). 使用您自己的库的预编译版本来提升编译速度. ...
- C++强大背后
转自MiloYip大神的博客 [原文]http://www.cnblogs.com/miloyip/archive/2010/09/17/behind_cplusplus.html 在31年前(197 ...
- <More Effective C#: 改善C#代码的50个有效方法>中文版翻译答疑
最近, 有一本很赞的.NET技术书中文版出版了 - <More Effective C#: 改善C#代码的50个有效方法>. 从广州\西安\长沙\上海等各地.NET俱乐部都收到反馈, ...
- Git新建分支,分支合并,版本回退详解
一.git基本命令 git拉取仓库代码 #拉取master代码 git clone git仓库地址 #拉取分支代码 git clone -b 分支名称 git仓库地址 2.git添加代码到本地仓库 g ...
- HashSet去重
class Program { static void Main(string[] args) { Console.WriteLine( ...
- python turtle画花
turtle是一个功能强调大的绘图的库,可以用来绘制各种所需要的图案,但是在使用时需要计算好角度等一系列的问题. 代码(源自<Python语言程序设计>)如下: 运行结果:
- Vue,Javascript--时间戳的操作
new Date(parseInt(data.substring(6, data.length - 2))).toLocaleDateString(); 我这里的data记得替换成你的数据,在过滤器中 ...