給定無重複元素的正整數數組 candidates 和目標值 target,找出所有組合使元素和等于 target。candidates 中的數字可無限次重複選取。解集不能包含重複組合,組合內元素非遞減序。
示例:candidates = [2,3,6,7], target = 7 → [[7], [2,2,3]]。
candidates 排序,便於剪枝與保證非遞減序。backtrack(start, path, remain):
start:當前搜索起始索引,避免排列重複(只考慮當前及之後的元素)。path:當前組合。remain:剩餘目標值。remain == 0,將 path 加入結果集。start 遍歷到末尾:
candidates[i] > remain,剪枝(後續更大)。candidates[i] 加入 path,遞歸調用 backtrack(i, path, remain - candidates[i])(注意傳 i 而非 i+1,允許重複使用)。path 最後元素。class Solution {
public:
vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
sort(candidates.begin(), candidates.end());
vector<vector<int>> result;
vector<int> path;
backtrack(candidates, target, 0, path, result);
return result;
}
private:
void backtrack(const vector<int>& candidates, int remain, int start,
vector<int>& path, vector<vector<int>>& result) {
if (remain == 0) {
result.push_back(path);
return;
}
for (int i = start; i < candidates.size(); ++i) {
if (candidates[i] > remain) break; // 剪枝
path.push_back(candidates[i]);
backtrack(candidates, remain - candidates[i], i, path, result);
path.pop_back();
}
}
};
i 而非 i+1 實現元素可重複使用。path 並手動 push/pop 避免拷貝開銷。