#include <unordered_map>
class Solution {
public:
//利用回溯的方法,进行凑数,每一层就是选与不选,
//这里有重复问题,也就是:选过的数字是不能再一次选的,而正在选或从来没有选过的可以选,使用数组记录,同种数字选过都不能再选了,如果用哈希表不能做到正在使用也可以重复选
vector<vector<int> > combinationSum2(vector<int>& num, int target) {
vector< int > temp;
vector< vector<int> > ans;
sort(num.begin(), num.end());
vector<int> mp(num.size(), 0);//初始化:0表示没有使用过;1表示正在使用;2表示使用过了;
dp(target, 0, temp, ans, num, mp);
return ans;
}
void dp(int target, int index, vector<int>& temp, vector< vector<int> >& ans, vector<int>& num, vector<int>& mp){
if( target == 0 ){
ans.push_back(temp);
return;
}
if( target < 0 || index >= num.size() ){
return;
}
//选
if( index > 0 && (num[index] == num[index-1] && mp[index-1] == 2) ){ //从来都没选过,或者选了,可以再选; 但是不能选过了,再选
mp[index] = 2; //前面相同的数使用过了,这个数不能使用,同时标记让后面相同的数也不能使用
}else{ //
temp.push_back( num[index] );
mp[ index ] = 1;
dp(target-num[index], index+1, temp, ans, num, mp);
temp.pop_back();
mp[ index ] = 2;
}
//不选, 不用在意
dp(target, index+1, temp, ans, num, mp);
return;
}
};