dfs算法模板:html
一、下一层是多节点的dfs遍历node
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 或者 还原以前的操做
不含重复元素的全排列模板,交换思路:python
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去重:app
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()
案例参考:ide
https://www.cnblogs.com/bonelee/p/11668685.htmlpost
https://www.cnblogs.com/bonelee/p/11667428.html测试
二、下一层仅2个节点的dfs,也就是二叉树的dfsthis
先序遍历,迭代和递归写法都要熟悉:
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总结: 一、第一次讲的dfs模板必定要记住。 二、二叉树的遍历,https://www.cnblogs.com/rnanprince/p/11595380.html,先序中序的递归和迭代写法必须掌握,像算法模板同样记住。后序遍历只掌握递归写法。 三、遍历过程当中须要记住上次遍历节点才能获得结果的,记住模板。 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) 四、BST的搜索代码要会,要记住。 五、排列组合类题目: 组合类算法,都使用分治+递归的思路去写,重复元素,先排序,无非多了一个判断。 排列类算法,用交换思路,都使用分治+递归的思路去写,重复元素,无非多了一个判断。 六、隐式图搜索:八皇后,正则表达式匹配,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(下边走) 走的过程当中将路径记下来 七、常见问题: 超时的处理:剪枝(cache、trie去剪枝),修改算法bfs,用dp 测试用例过不完:本身debug,放到ide去调试