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