Given a set of candidate numbers (candidates
) (without duplicates) and a target number (target
), find all unique combinations in candidates
where the candidate numbers sums to target
.
The same repeated number may be chosen from candidates
unlimited number of times.
Note:
- All numbers (including
target
) will be positive integers. - The solution set must not contain duplicate combinations.
Example 1:
Input: candidates =[2,3,6,7],
target =7
, A solution set is: [ [7], [2,2,3] ]
Example 2:
Input: candidates = [2,3,5],
target = 8,
A solution set is:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
對於一個給出的數target和一個數集C,問存在多少種不同的方案,使得可以從數集C中選出若干個數(每個數可以選擇無限次)使得這些數的和等於target。
新題中沒有:
- Elements in a combination (a1, a2, … , ak) must be in non-descending order. (ie, a1 ≤ a2 ≤ … ≤ ak).
如果有這個要求就要對數組C排序,使用過的就不能在使用了,因為會要保證大小順序。
解法:遞歸 + backtracking, 注意數組的mutable.
Java:
public class Solution { public List<List<Integer>> combinationSum(int[] candidates, int target) { List<List<Integer>> res = new ArrayList<>(); if (candidates == null) return res; Arrays.sort(candidates); getCombinations(res, new ArrayList<>(), candidates, target, 0); return res; } private void getCombinations(List<List<Integer>> res, List<Integer> list, int[] nums, int target, int pos) { if (target < 0) return; if (target == 0) { res.add(new ArrayList<>(list)); return; } for (int i = pos; i < nums.length; i++) { if (nums[i] > target) break; if (i > pos && nums[i] == nums[i - 1]) continue; list.add(nums[i]); getCombinations(res, list, nums, target - nums[i], i); list.remove(list.size() - 1); } } }
Python:
class Solution: # @param candidates, a list of integers # @param target, integer # @return a list of lists of integers def combinationSum(self, candidates, target): result = [] self.combinationSumRecu(sorted(candidates), result, 0, [], target) return result def combinationSumRecu(self, candidates, result, start, intermediate, target): if target == 0: result.append(list(intermediate)) while start < len(candidates) and candidates[start] <= target: intermediate.append(candidates[start]) self.combinationSumRecu(candidates, result, start, intermediate, target - candidates[start]) intermediate.pop() start += 1
Python: wo
class Solution(object): def combinationSum(self, candidates, target): """ :type candidates: List[int] :type target: int :rtype: List[List[int]] """ res = [] self.helper(res, sorted(candidates), [], 0, 0, target) return res def helper(self, res, candidates, cur, temp, pos, target): if temp > target: return if temp == target: res.append(cur) for i in range(pos, len(candidates)): self.helper(res, candidates, cur + [candidates[i]], temp + candidates[i], i, target)
C++:
class Solution { public: vector<vector<int>> combinationSum(vector<int>& candidates, int target) { // 注意candidates不是有序的,要先排序處理 sort(candidates.begin(), candidates.end()); // 用以記錄答案和當前方案 vector<vector<int>> ans; vector<int> current; // 開始回溯搜索 backtracking(ans, candidates, current, 0, target); // 返回答案 return ans; } void backtracking(vector<vector<int>>& ans, vector<int>& candidates, vector<int> current, int last_use, int rest_target) { // 當rest_target等於0時,說明已經找到了一組合法的方案 if (rest_target == 0) { // 故將其加入到答案當中 ans.push_back(current); } // 否則就枚舉下一個加入到current中的數,在枚舉中注意2個條件 // i >= last_use,保證current是非遞減的 // candidates[i] <= rest_target,保證rest_target不小於0 for (int i = last_use; i < candidates.size() && candidates[i] <= rest_target; i++) { // 放入current中 current.push_back(candidates[i]); // 繼續搜索下一個數字 backtracking(ans, candidates, current, i, rest_target - candidates[i]); // 回溯處理 current.pop_back(); } } };
類似題目:
[LeetCode] 40. Combination Sum II 組合之和 II
[LeetCode] 216. Combination Sum III 組合之和 III
[LeetCode] 377. Combination Sum IV 組合之和 IV
[LeetCode] 90. Subsets II 子集合 II
[LeetCode] 46. Permutations 全排列
[LeetCode] 47. Permutations II 全排列 II
[LeetCode] 131. Palindrome Partitioning 回文分割
All LeetCode Questions List 題目匯總