給定候選數組 candidates(無重複元素)與目標值 target,找出所有數字和為 target 的組合。每個數字可無限次使用。解集不能包含重複組合,組合內元素非遞減序。
candidates,便於剪枝與保證非遞減序。dfs(index, sum):sum == target,記錄當前路徑。sum > target,剪枝返回。index 開始遍歷:選擇 candidates[i],遞歸 dfs(i, sum + candidates[i])(注意傳 i 而非 i+1,允許重複使用),回溯移除。sum + candidates[i] > target 可直接 break。class Solution {
public:
void dfs(vector<int>& candidates, int index, int sum, int target,
vector<vector<int>>& res, vector<int>& path) {
if (sum > target) return;
if (sum == target) { res.push_back(path); return; }
for (int i = index; i < candidates.size(); ++i) {
if (sum + candidates[i] > target) break; // 剪枝
path.push_back(candidates[i]);
dfs(candidates, i, sum + candidates[i], target, res, path);
path.pop_back();
}
}
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(), candidates.end());
vector<vector<int>> res;
vector<int> path;
dfs(candidates, 0, 0, target, res, path);
return res;
}
};
target / min(candidates),路徑存儲 O(target)。candidates = [2,3,6,7], target = 7 輸出: [[7], [2,2,3]]
index 而非 index+1 實現「可重複使用」。index 開始枚舉,保證組合非遞減且無重複。sum + candidates[i] > target 時 break。