之前写一些题比如:
的时候,经常用
的方式来去重,但这样有一个问题:这样去重的前提是有序数组(也就是事先排好序的)
!!!重点来了
但在这个题中,不能惯性思维,这个题不能改变数组顺序,因此不能用类似双指针的思想来去重.本题应用哈希表去重
之前错误的代码:
class Solution {
public:
vector<vector<int>> ans;
vector<int> result;
void backtracking(vector<int>& nums, int startindex){
if(result.size() >= 2){
ans.push_back(result);
}
if(startindex >= nums.size()){
return;
}
for(int i = startindex; i < nums.size(); i++){//还要去重
if(i > startindex && nums[i] == nums[i-1]) continue;//这里有问题
if(result.size() == 0 || nums[i] >= result[result.size()-1]){
result.push_back(nums[i]);
backtracking(nums,i+1);
result.pop_back();
}
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
backtracking(nums,0);
return ans;
}
};
正确代码:
class Solution {
public:
vector<vector<int>> ans;
vector<int> result;
void backtracking(vector<int>& nums, int startindex){
if(result.size() >= 2){
ans.push_back(result);
}
if(startindex >= nums.size()){
return;
}
unordered_set<int> hash;//这个哈希表每一层用
for(int i = startindex; i < nums.size(); i++){
if(!result.empty() && result.back() > nums[i]
|| hash.count(nums[i])){
continue;
}
result.push_back(nums[i]);
hash.insert(nums[i]);
backtracking(nums,i+1);
result.pop_back();
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
backtracking(nums,0);
return ans;
}
};
两者去重的本质都一样:都是同一树层上不能取相同的元素
只不过用类似双指针思想去重数组必须有序!!!
本题数据量比较小,也可以考虑用数组,这样运行速度更快。用数组的代码如下:
class Solution {
public:
vector<vector<int>> ans;
vector<int> result;
void backtracking(vector<int>& nums, int startindex){
if(result.size() >= 2){
ans.push_back(result);
}
if(startindex >= nums.size()){
return;
}
int hash[201] = {0};
for(int i = startindex; i < nums.size(); i++){
if(!result.empty() && result.back() > nums[i]
|| hash[100+nums[i]] == 1){
continue;
}
result.push_back(nums[i]);
hash[nums[i]+100]++;
backtracking(nums,i+1);
result.pop_back();
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
backtracking(nums,0);
return ans;
}
};
可以看到两者差异还是比较大的,数据量比较小时优先考虑用数组来模拟哈希表