class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums,int startIndex){
result.push_back(path);//和组合问题区别的是,这里只是单纯遍历,只限制组合是否重复,
if(startIndex>=nums.size()){
return;
}
for(int i=startIndex;i<nums.size();i++){//这里把i设置成index,防止重复
path.push_back(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
public:
vector<vector<int>> subsets(vector<int>& nums) {
backtracking(nums,0);
return result;
}
};
主要区别组合问题即可
思路:区别上题,本题会有重复元素,但又不能包含重复的子集,所以要做到去重
我总结了去重的二要素,在注释中
class Solution {
private:
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>& nums,int startIndex){
result.push_back(path);
for(int i=startIndex;i<nums.size();i++){
if(i>startIndex&&nums[i]==nums[i-1]){//去重一要素,保证去重元素不是第一个即i>index
continue;
}
path.push_back(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
public:
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(), nums.end());//去重第二要素,保证重复数字相邻
backtracking(nums,0);
return result;
}
};
总结:回溯就是一个巨大的板子,各种情况可以不同组合,不同情况又有其对应的板子,只要板子熟练,这类题目不难