代码随想录算法训练营第二十四天 | 回溯算法开篇,77.组合

回溯算法开篇:理论及概览

  • 回溯函数就是递归函数
  • 递归函数下面就包含回溯
  • 回溯搜索法,纯暴力搜索——有些结果能暴力搜索出来就很不错了
  • 为什么要学习回溯?能解决哪些问题?
    • 组合问题【无顺序】——排列组合
    • 切割问题:给一个字符串,问如何切割?
    • 子集问题——类似组合
    • 排列问题【强调顺序】
    • 棋盘问题
      • 如:N皇后题目
    • 题目概览:
  • 代码随想录算法训练营第二十四天 | 回溯算法开篇,77.组合_第1张图片

  • 如何理解回溯法?
    • 可以抽象为树形结构——N叉树
    • 模板
      • 没有返回值——通用命名:backtracking
      • 终止条件:收集结果——return
      • 单层搜索逻辑:
        • for循环(放集合的元素集:每一个元素)
        • 处理节点
        • 递归函数
          • 回溯操作:撤销处理节点的操作——why?——为了得到新的结果

77.组合

题目:

给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。

你可以按 任何顺序 返回答案。

思路:

第一次做肯定是没有思路的。跟着视频和参考的代码看下来,还是递归三部曲,重要的是参数变多了,需要分清楚各自的作用。

path:第一层

result:接受最终结果

startIndex:第一层里包含的起始数

n:一共有多少个数

k:组合包含的元素的个数

代码:

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:  # 参数和返回值
        result = []  # 接收最终结果
        self.backtracking(n, k, 1, [], result)
        return result

    def backtracking(self, n, k, startIndex, path, result):  # path 一维数组  result 二维数组  包含的参数
        # 确定终止条件:到叶子节点
        if len(path) == k:
            result.append(path[:])  # 重要!对path进行切片,生成新的数组,避免后面回溯对其产生影响。
            return result
        # 遍历
        for i in range(startIndex, n + 1):
            path.append(i)
            self.backtracking(n, k, i + 1, path, result)
            path.pop()  # 回溯!很重要,弹出后再返回上层,继续找新的组合

你可能感兴趣的:(算法,数据结构)