1. 程式人生 > 實用技巧 >Combination Sum II

Combination Sum II

Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidateswhere the candidate numbers sums to target.

Each number in candidatesmay only be used once in the combination.

Note:

All numbers (including target) will be positive integers.
The solution set must not contain duplicate combinations.

Example 1:

Input: candidates =[10,1,2,7,6,1,5], target =8,
A solution set is:
[
[1, 7],
[1, 2, 5],
[2, 6],
[1, 1, 6]
]
Example 2:

Input: candidates =[2,5,2,1,2], target =5,
A solution set is:
[
[1,2,2],
[5]
]

class Solution {
public:
    vector<pair<int,int>> freg;
    vector<vector<int
>> ans; vector<int> sequence; void dfs(int pos,int rest){ if(rest == 0){ ans.emplace_back(sequence); return; } if(pos == freg.size() || rest<freg[pos].first){ return;//加上最後一個數後,超過了對應的target } dfs(pos+1,rest);
int most = min(rest/freg[pos].first,freg[pos].second); for(int i=1;i<=most;++i){ sequence.emplace_back(freg[pos].first); dfs(pos+1,rest-i*freg[pos].first); } for(int i=1;i<=most;++i){ sequence.pop_back();//恢復現場,為了便於後面的進一步遞迴 } } vector<vector<int>> combinationSum2(vector<int>& candidates, int target) { sort(candidates.begin(),candidates.end()); for(int num:candidates){ if(freg.empty() || num!=freg.back().first){ freg.emplace_back(num,1); } else{ ++freg.back().second; } } dfs(0,target); return ans; } };

注意:1.回溯的方式,對於列表中的每個數都有兩種選擇,選擇或者不被選擇,類似一個二叉樹的方式進行遞迴。2.為了避免重複列舉,將所有一樣的數字放在一起,按照該數字可能出現的次數,逐個進行列舉判斷。