算法记录 | Day11回溯算法

102 阅读1分钟

算法记录 | Day11回溯算法

因为太忙了,所以一整个二叉树的一章都没做,之后慢慢补,今天先跟回溯。

回溯法,一般可以解决如下几种问题:

  • 组合问题:N个数里面按一定规则找出k个数的集合
  • 切割问题:一个字符串按一定规则有几种切割方式
  • 子集问题:一个N个数的集合里有多少符合条件的子集
  • 排列问题:N个数按一定规则全排列,有几种排列方式
  • 棋盘问题:N皇后,解数独等等

LeetCode 77-组合

题目描述:给定两个整数 nk,返回范围 [1, n] 中所有可能的 k 个数的组合。你可以按 任何顺序 返回答案。

题目链接:leetcode.cn/problems/co…

输入:n = 4, k = 2
输出:
[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]
解题思路
  • 回溯算法
  • 有点迷糊,有些懂,但不知如何写的。
class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        res = []
        path = []
        def backtrack(n, k, startidx):
            if len(path) == k:
                res.append(path[:])
                return
            for i in range(startidx,n+1):
                path.append(i)
                backtrack(n,k,i+1)
                path.pop()
        backtrack(n,k,1)
        return res

关于剪枝操作

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:
        res=[]  #存放符合条件结果的集合
        path=[]  #用来存放符合条件结果
        def backtrack(n,k,startIndex):
            if len(path) == k:
                res.append(path[:])
                return
            for i in range(startIndex,n-(k-len(path))+2):  #优化的地方
                path.append(i)  #处理节点
                backtrack(n,k,i+1)  #递归
                path.pop()  #回溯,撤销处理的节点
        backtrack(n,k,1)
        return res
难点
  • 有了模板之后,总是想着套模板,没有清楚地了解过程
  • 剪枝操作可以怎么用
收获
  • 回溯算法的模板。
  • debug之后思路稍微清晰了一点,但还是主要靠背诵。