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去调试