递增子序列
本题的难点在于细节上的处理:
1.大于=2时才能加入
2.不能排序,如何做到树层去重
cpp
void backtracking(vector<int> nums,int startindex){
if(path.size()>=2)
result.push_back(path);
//都是在结点处处理
if(startindex==nums.size())
return;
unordered_set<int> usedset;
//用set来记录树层中遍历过的
for(int i=startindex;i<nums.size();i++){
if((!path.empty()&&path.back()>nums[i])||usedset.find(nums[i])!=usedset.end())
//如果当前的比path中的末尾大/出现过,就接着往下选
{
continue;
}
usedset.insert(nums[i]);
path.push_back(nums[i]);
backtracking(nums,i+1);
path.pop_back();
}
}
关于set
要在每一层都设立一个新的set,这样在递归到下一层时并不会有影响,而在同一层的则可以实现去重
全排列
在组合问题中,为了防止统计重复过的元素,我们用了startindex来判断位置起点。
而排列问题1,2;2,1是两种不同的答案,并不需要从遍历过的地方的下一个位置开始,
所以
for(int i=0;;)
面对排列问题可以用used数组来记录那些地方遍历过。
cpp
void backtracking(vector<int> nums,vector<int>used){
if(path.size()==nums.size()){
result.push_back(path);
return;
}
for(int i=0;i<nums.size();i++){
if(used[i]==1)
continue;
used[i]=1;
path.push_back(nums[i]);
backtracking(nums,used);
path.pop_back();
used[i]=0;
}
}
全排列2
这题的区别就是需要做数层上的去重
数层上的去重有两种方法:
1.在每一层都定义一个set,如果能在本层的set中找到说明这层中已经有该数字,continue
2.看nums[i]==nums[i-1],但这样判断在这里有一个难点:同层和同枝都可以满足这个。
前面组合用这个判断的时候已经去除了遍历过的元素,比如1,1,2;在i=1时它的startindex也是1。
但是在这里没一次都是从0开始,所以可以将它进行排序,如果还满足i-1没有被用过,则说明是同层
第一种写法
cpp
void backtracking(vector<int>nums,vector<int> used){
if(path.size()==nums.size()){
result.push_back(path);
return;
}
set<int> ceng;
for(int i=0;i<nums.size();i++){
if(used[i]==1||ceng.find(nums[i])!=ceng.end())
continue;
used[i]=1;
ceng.insert(nums[i]);
path.push_back(nums[i]);
backtracking(nums,used);
path.pop_back();
used[i]=0;
}
}
第二种写法
cpp
vector<vector<int>> result;
vector<int> path;
void backtracking(vector<int>nums,vector<int> used){
if(path.size()==nums.size()){
result.push_back(path);
return;
}
for(int i=0;i<nums.size();i++){
if((i>0&&nums[i]==nums[i-1])&&used[i-1]==0)
continue;
if(used[i]==1)
continue;
used[i]=1;
path.push_back(nums[i]);
backtracking(nums,used);
path.pop_back();
used[i]=0;
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
sort(nums.begin(),nums.end());
vector<int> used(nums.size());
backtracking(nums,used);
return result;
}