DFS 算法模板

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去调试
相关文章
相关标签/搜索