代码随想录第24天 | 回溯法 77. 组合

46 阅读1分钟

77. 组合

1. first idea

回溯不返回任何参数,

找一个全局的list存储遍历到叶子节点后满足要求的结果。

广度优先遍历,注意要保证当前遍历到的值不能是之前tmp_list已经有的。

如果按照递增地次序遍历,正常情况下就不需要考虑新的tmp_list中的组合会在汇总全局list出现过。

class Solution:
    def __init__(self):
        self.res_list = []

    def backtracking(self, tmp_list, n, k):
        if len(tmp_list) == k:
            self.res_list.append(tmp_list)
            return
        else:
            start_idx = 1 if not tmp_list else tmp_list[-1] + 1
            for i in range(start_idx, n + 1):
                self.backtracking(tmp_list + [i], n, k)

    def combine(self, n: int, k: int) -> List[List[int]]:
        self.backtracking([], n, k)
        return self.res_list

2. 剪枝

读了代码随想录 (programmercarl.com),我看到了一种剪枝思想。 如果我们当前遍历到一个元素,[1,n][1,n]中剩下的可供加入tmp_list的元素个数一定要够k -tmp_list - 1个。 不然也没有继续遍历的需要了,不够多元素一定攒不够一个可能结果。

class Solution:
    def __init__(self):
        self.res_list = []

    def backtracking(self, tmp_list, n, k):
        if len(tmp_list) == k:
            self.res_list.append(tmp_list)
            return
        else:
            start_idx = 1 if not tmp_list else tmp_list[-1] + 1
            for i in range(start_idx, n - (k - len(tmp_list) - 1) + 1):
                self.backtracking(tmp_list + [i], n, k)

    def combine(self, n: int, k: int) -> List[List[int]]:
        self.backtracking([], n, k)
        return self.res_list

2. learning time

80分钟。