文章目录
Leetcode90
1.问题描述
2.解决方案
总结:
说白了本题相对于78.子集只多了一个排序加同层去重,这道题三种解法属于是把同层去重,全部家当讲明白了,这道题代码xslPDF没有但是刷题网站上有
解法一:最经典的参数传used数组去重(效率高)
同层去重
if(i!=0&&nums[i]==nums[i-1]&&used[i-1]== false) continue;
class Solution {
public:
vector<vector<int>> ans;
vector<int> path;
void backtracking(vector<int>& nums,int startIndex,vector<bool> used){
ans.push_back(path);
if(startIndex>=nums.size()) return;
for(int i=startIndex;i<nums.size();i++){
//排序后的同层去重
if(i!=0&&nums[i]==nums[i-1]&&used[i-1]== false) continue;
path.push_back(nums[i]);
used[i]=true;
backtracking(nums,i+1,used);
used[i]= false;
path.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
//排序
sort(nums.begin(),nums.end());
vector<bool> used(nums.size(), false);
backtracking(nums,0,used);
return ans;
}
};
解法二:由于是同层去重自然可以使用uSet去重(效率较低)
uSet只记录同层故同层去重
//排序后的同层去重
unordered_set<int> uSet;
for(int i=startIndex;i<nums.size();i++){
if(uSet.find(nums[i])!=uSet.end()) continue;
class Solution1 {
public:
vector<vector<int>> ans;
vector<int> path;
void backtracking(vector<int>& nums,int startIndex){
ans.push_back(path);
if(startIndex>=nums.size()) return;
//排序后的同层去重
unordered_set<int> uSet;
for(int i=startIndex;i<nums.size();i++){
if(uSet.find(nums[i])!=uSet.end()) continue;
path.push_back(nums[i]);
uSet.insert(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
//排序
sort(nums.begin(),nums.end());
backtracking(nums,0);
return ans;
}
};
解法三:完全理解之后的去重逻辑,used,uSet都不使用(效率最高)
很好的理解,第一种肯定不对,第一种不仅对同层的去重,同一路径也去重了这是不对的,而第二种就得好好理解了,加了一个 i>startIndex 的限制条件,就相当于说我只有在i=startIndex i=startIndex+1…也就是同一层比较,而进去递归下一层由于 i==startIndex直接跳过这也避免了同一路径的去重,非常重要!!!
//1.不仅对同层对同一路径也去重了
//if(i!=0&&nums[i]==nums[i-1]) continue;
//2.排序后的同层去重 重点:我们要对同一树层使用过的元素进行跳过
if(i>startIndex&&nums[i]==nums[i-1]) continue;
class Solution2 {
public:
vector<vector<int>> ans;
vector<int> path;
void backtracking(vector<int>& nums,int startIndex){
ans.push_back(path);
if(startIndex>=nums.size()) return;
for(int i=startIndex;i<nums.size();i++){
//1.不仅对同层对同一路径也去重了
//if(i!=0&&nums[i]==nums[i-1]) continue;
//2.排序后的同层去重 重点:我们要对同一树层使用过的元素进行跳过
if(i>startIndex&&nums[i]==nums[i-1]) continue;
path.push_back(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
//排序
sort(nums.begin(),nums.end());
backtracking(nums,0);
return ans;
}
};