39. 组合总和
给你一个 无重复元素 的整数数组 candidates
和一个目标整数 target
,找出 candidates
中可以使数字和为目标数 target
的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。
candidates
中的 同一个 数字可以 无限制重复被选取 。如果至少一个数字的被选数量不同,则两种组合是不同的。
对于给定的输入,保证和为 target
的不同组合数少于 150
个。
示例 1:
输入:candidates =[2,3,6,7],
target =7
输出:[[2,2,3],[7]] 解释: 2 和 3 可以形成一组候选,2 + 2 + 3 = 7 。注意 2 可以使用多次。 7 也是一个候选, 7 = 7 。 仅有这两种组合。
示例 2:
输入: candidates = [2,3,5],
target = 8
输出: [[2,2,2,2],[2,3,3],[3,5]]
示例 3:
输入: candidates = [2],
target = 1
输出: []
提示:
1 <= candidates.length <= 30
1 <= candidates[i] <= 200
candidate
中的每个元素都 互不相同1 <= target <= 500
原站题解
cpp 解法, 执行用时: 4 ms, 内存消耗: 13.2 MB, 提交时间: 2024-04-20 10:44:14
class Solution { public: vector<vector<int>> combinationSum(vector<int>& candidates, int target) { ranges::sort(candidates); vector<vector<int>> ans; vector<int> path; function<void(int, int)> dfs = [&](int i, int left) { if (left == 0) { // 找到一个合法组合 ans.push_back(path); return; } if (left < candidates[i]) { return; } // 枚举选哪个 for (int j = i; j < candidates.size(); j++) { path.push_back(candidates[j]); dfs(j, left - candidates[j]); path.pop_back(); // 恢复现场 } }; dfs(0, target); return ans; } };
cpp 解法, 执行用时: 12 ms, 内存消耗: 16.3 MB, 提交时间: 2024-04-20 10:44:02
class Solution { public: vector<vector<int>> combinationSum(vector<int>& candidates, int target) { ranges::sort(candidates); vector<vector<int>> ans; vector<int> path; function<void(int, int)> dfs = [&](int i, int left) { if (left == 0) { // 找到一个合法组合 ans.push_back(path); return; } if (i == candidates.size() || left < candidates[i]) { return; } // 不选 dfs(i + 1, left); // 选 path.push_back(candidates[i]); dfs(i, left - candidates[i]); path.pop_back(); // 恢复现场 }; dfs(0, target); return ans; } };
java 解法, 执行用时: 2 ms, 内存消耗: 43.7 MB, 提交时间: 2024-04-20 10:43:47
class Solution { public List<List<Integer>> combinationSum(int[] candidates, int target) { Arrays.sort(candidates); List<List<Integer>> ans = new ArrayList<>(); List<Integer> path = new ArrayList<>(); dfs(0, target, candidates, ans, path); return ans; } private void dfs(int i, int left, int[] candidates, List<List<Integer>> ans, List<Integer> path) { if (left == 0) { // 找到一个合法组合 ans.add(new ArrayList<>(path)); return; } if (i == candidates.length || left < candidates[i]) { return; } // 不选 dfs(i + 1, left, candidates, ans, path); // 选 path.add(candidates[i]); dfs(i, left - candidates[i], candidates, ans, path); path.remove(path.size() - 1); // 恢复现场 } }
java 解法, 执行用时: 2 ms, 内存消耗: 43.6 MB, 提交时间: 2024-04-20 10:43:35
class Solution { public List<List<Integer>> combinationSum(int[] candidates, int target) { Arrays.sort(candidates); List<List<Integer>> ans = new ArrayList<>(); List<Integer> path = new ArrayList<>(); dfs(0, target, candidates, ans, path); return ans; } private void dfs(int i, int left, int[] candidates, List<List<Integer>> ans, List<Integer> path) { if (left == 0) { // 找到一个合法组合 ans.add(new ArrayList<>(path)); return; } if (left < candidates[i]) { return; } // 枚举选哪个 for (int j = i; j < candidates.length; j++) { path.add(candidates[j]); dfs(j, left - candidates[j], candidates, ans, path); path.remove(path.size() - 1); // 恢复现场 } } }
golang 解法, 执行用时: 0 ms, 内存消耗: 2.8 MB, 提交时间: 2024-04-20 10:43:19
func combinationSum(candidates []int, target int) (ans [][]int) { slices.Sort(candidates) path := []int{} var dfs func(int, int) dfs = func(i, left int) { if left == 0 { // 找到一个合法组合 ans = append(ans, slices.Clone(path)) return } if i == len(candidates) || left < candidates[i] { return } // 不选 dfs(i+1, left) // 选 path = append(path, candidates[i]) dfs(i, left-candidates[i]) path = path[:len(path)-1] // 恢复现场 } dfs(0, target) return ans } func combinationSum2(candidates []int, target int) (ans [][]int) { slices.Sort(candidates) path := []int{} var dfs func(int, int) dfs = func(i, left int) { if left == 0 { // 找到一个合法组合 ans = append(ans, slices.Clone(path)) return } if left < candidates[i] { return } // 枚举选哪个 for j := i; j < len(candidates); j++ { path = append(path, candidates[j]) dfs(j, left-candidates[j]) path = path[:len(path)-1] // 恢复现场 } } dfs(0, target) return ans }
python3 解法, 执行用时: 45 ms, 内存消耗: 16.6 MB, 提交时间: 2024-04-20 10:42:42
class Solution: def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: ans = [] path = [] def dfs(i: int, left: int) -> None: if left == 0: # 找到一个合法组合 ans.append(path.copy()) return if i == len(candidates) or left < 0: return # 不选 dfs(i + 1, left) # 选 path.append(candidates[i]) dfs(i, left - candidates[i]) path.pop() # 恢复现场 dfs(0, target) return ans
python3 解法, 执行用时: 56 ms, 内存消耗: 13.5 MB, 提交时间: 2020-09-09 21:34:29
class Solution: def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]: candidates.sort() n = len(candidates) res = [] def backtrack(i, tmp_sum, tmp): if tmp_sum > target or i == n: return if tmp_sum == target: res.append(tmp) return for j in range(i, n): if tmp_sum + candidates[j] > target: break backtrack(j, tmp_sum + candidates[j], tmp + [candidates[j]]) backtrack(0, 0, []) return res