"""
给定一个无重复元素的数组 candidates 和一个目标数 target ，找出 candidates 中所有可以使数字和为 target 的组合。

candidates 中的数字可以无限制重复被选取。

说明：

所有数字（包括 target）都是正整数。
解集不能包含重复的组合。 
示例 1：

输入：candidates = [2,3,6,7], target = 7,
所求解集为：
[
  [7],
  [2,2,3]
]
示例 2：

输入：candidates = [2,3,5], target = 8,
所求解集为：
[
  [2,2,2,2],
  [2,3,3],
  [3,5]
]

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/combination-sum
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
"""

# 这种回溯法最好你自己把搜索树画一下，然后写起来特别容易
from typing import *
import copy

def combinationSum(candidates: List[int], target: int) -> List[List[int]]:
    # candidates = sorted(candidates)
    def dfs(candidates, target, combines, index):
        if target == 0:
            return [combines]
        elif target < 0:
            return []

        all_combines = []
        for i in range(index, len(candidates)):
            next_combine = copy.copy(combines)
            next_combine.append(candidates[i])
            to_extend = dfs(candidates, target - candidates[i], next_combine, i)
            all_combines.extend(to_extend)
        return all_combines

    return dfs(candidates, target, [], 0)


if __name__ == '__main__':
    print(combinationSum([2, 3, 4, 7], 7))