39. Combination Sum

https://leetcode.com/problems/combination-sum/

solution

(可以换一种问法,从3 sum而来的k-sum,给定array和target,返回全部可以总和到target的group)

  • 有放回+控制重复。注意理解这里的需求,有放回是当下的元素可以无限取,但不能从过去元素取,否则造成结果重复。(元素可以重复,结果不能重复)

  • 回溯时,每次的开始start仍然由i进行,小于0时进行剪枝(因此需要排序)

  • 寻找某个target的dfs,都是target-item来递归。回溯是否需要再加回去?

class Solution:
    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        res = []
        path = []
        # candidates.sort()
        self.dfs(path, res, candidates, target, start=0)
        return res

    def dfs(self, path, res, candidates, target, start):
        if target < 0:  # 剪枝, 一定要有这步?
            return

        if target == 0:
            res.append(path[:])
            return

        for i in range(start, len(candidates)):
            path.append(candidates[i])
            self.dfs(path, res, candidates, target - candidates[i], i)  # 有放回i, 无放回i+1
            path.pop()

时间复杂度:O(candidates^target) 空间复杂度:O(target)

follow up

40. Combination Sum II

  • 无放回,控制开始的index每次i+1,而不是i

  • 控制重复,采用排序加剪枝。for循环横向遍历,对同一层使用过的元素跳过

时间复杂度:O(n⋅2^n) 空间复杂度:O(n+n⋅2^n)

216. Combination Sum III

  • 不重复,开始从i+1

  • 规定了选取的个数

时间复杂度:O(9! / (9 - k)!) 空间复杂度:O(C(9, k))

时间复杂度:O() 空间复杂度:O()

377. Combination Sum IV

494. Target Sum

  • 动态规划/背包

473. Matchsticks to Square

Last updated