秋招算法备战第24天 | 回溯算法理论基础、77. 组合

回溯算法理论基础

回溯三部曲

  1. 回溯函数模板返回值以及参数
  2. 回溯函数终止条件
  3. 回溯搜索的遍历过程

回溯算法模板框架如下:

void backtracking(参数) {
    if (终止条件) {
        存放结果;
        return;
    }

    for (选择:本层集合中元素(树中节点孩子的数量就是集合的大小)) {
        处理节点;
        backtracking(路径,选择列表); // 递归
        回溯,撤销处理结果
    }
}

77. 组合 - 力扣(LeetCode)

按照模板把写出来了

class Solution:
    def combine(self, n: int, k: int) -> List[List[int]]:

        result = []
        path = []


        def backtracking(start_index, count):
            if count == k:
                result.append(path[:])
            
            for i in range(start_index, n):
                path.append(i+1)
                backtracking(i+1, count+1)
                path.pop()
        
        backtracking(0, 0)
        return result

下面是GPT4的优化,发现自己在终止条件那里忘记return了

您的代码实现非常清晰,对于生成n个数的所有k个组合,已经实现了一个有效的解决方案。我会对代码进行一些微小的优化,以减少不必要的操作并增加代码的可读性。

首先,如果在循环中达到了count == k的条件,我们可以立即停止后续循环,避免执行多余的操作。其次,为了代码的可读性,我们可以使用一个更有描述性的变量名代替start_indexcount。以下是优化后的代码:

    def combine(self, n: int, k: int) -> List[List[int]]:
        result = []
        path = []

        def backtracking(start, depth):
            if depth == k:
                result.append(path[:])
                return  # Once we reach the required depth, we stop

            for i in range(start, n):
                path.append(i+1)
                backtracking(i+1, depth+1)
                path.pop()

        backtracking(0, 0)
        return result ```

这里我们使用了`depth`代替`count`,因为我们实际上在递归树中的深度。使用`start`代替`start_index`可以简化代码。同时在`depth
== k`时,我们增加了一个return,这可以停止当前层次的后续循环,避免进行无用的循环。

最后,这些优化主要是针对代码的可读性和简洁性,不会对性能有显著提升,因为你的原始实现已经相当高效了。

代码随想录的参考代码如下

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):
        if len(path) == k:
            result.append(path[:])
            return
        for i in range(startIndex, n - (k - len(path)) + 2):  # 优化的地方
            path.append(i)  # 处理节点
            self.backtracking(n, k, i + 1, path, result)
            path.pop()  # 回溯,撤销处理的节点

总结

回溯模板的写法需要掌握

你可能感兴趣的:(算法)