90.子集II
有点像子集I和之前做过的一个去重的结合
记得先排序
class Solution {
public:
vector<vector<int>> result;
vector<int> each;
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<bool> used(nums.size(), false);
nums.push_back(0);
backTrace(nums, 0, used);
return result;
}
void backTrace (vector<int>& nums, int index, vector<bool> used){
int n = nums.size();
if(index >= n){
result.push_back(each);
return;
}
for(int i = index; i< n; ++i){
if(i == n-1 && nums[i]==0){
backTrace(nums, i+1, used);
}
else if(i > 0 && nums[i]==nums[i-1] && used[i-1] == false){
continue;
}
else{
each.push_back(nums[i]);
used[i]=true;
backTrace(nums, i+1, used);
used[i]=false;
each.pop_back();
}
}
}
};
A c 下一题
491.非递减子序列
这题不能sort
要按原来顺序给出非递减子序列
而本题求自增子序列,是不能对原数组进行排序的,排完序的数组都是自增子序列了。
所以不能使用之前的去重逻辑!
这里的去重就不使用used数组,而是在每层用一个哈希表去重(也不需要传参,在本层不重复就可以)
class Solution {
public:
vector<vector<int>> result;
vector<int> each;
vector<vector<int>> findSubsequences(vector<int>& nums) {
nums.push_back(0);
backTrace(nums, 0);
return result;
}
void backTrace(vector<int>& nums, int index) {
int n = nums.size();
unordered_set<int> set;
if (index >= n) {
if (each.size() >= 2) {
result.push_back(each);
}
return;
}
for (int i = index; i < n; ++i) {
if (i == n - 1 && nums[i] == 0) {
backTrace(nums, i + 1);
} else if (set.find(nums[i]) == set.end() &&
(each.size() == 0 || each[each.size() - 1] <= nums[i])) {
set.insert(nums[i]);
each.push_back(nums[i]);
backTrace(nums, i + 1);
each.pop_back();
}
}
}
};
本层回溯逻辑:
插入的元素要大于等于当前each数组最后一个元素,或者each为空可以直接插入,
同时需要在哈希表中没出现过的元素(本层新建哈希表,不需要传参)
同时考虑可能这层啥也不选的可能(在nums最后添0)
46.全排列
需要回头找,所以不用设置index,反而用used数组来纵向(在递归过程中而非在本层中)表示哪些是被选择过的
class Solution {
public:
vector<vector<int>> result;
vector<int> each;
vector<vector<int>> permute(vector<int>& nums) {
vector<bool> used(nums.size(), false);
backTrace(nums, used);
return result;
}
void backTrace(vector<int>& nums, vector<bool> used) {
int n = nums.size();
if (each.size() == n) {
result.push_back(each);
return;
}
for (int i = 0; i < n; ++i) {
if (used[i] == false) {
each.push_back(nums[i]);
used[i] = true;
backTrace(nums, used);
used[i] = false;
each.pop_back();
}
}
}
};
47.全排列 II
先sort后用used,在本层横向和递归纵向都去重的结合
class Solution {
public:
vector<vector<int>> result;
vector<int> each;
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(), nums.end());
vector<bool> used(nums.size(), false);
backTrace(nums,used);
return result;
}
void backTrace(vector<int>& nums, vector<bool>& used){
int n = nums.size();
if(each.size() == n){
result.push_back(each);
return;
}
for(int i = 0; i<n; ++i){
if(used[i] == true || (i>0 && used[i-1]==false && nums[i]==nums[i-1])){
continue;
}
else{
used[i]=true;
each.push_back(nums[i]);
backTrace(nums,used);
each.pop_back();
used[i]=false;
}
}
}
};
Ac
开启回溯算法最后一part!!