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去調試