491.递增子序列
文档讲解:代码随想录
视频讲解: 回溯算法精讲,树层去重与树枝去重 | LeetCode:491.递增子序列
状态
对于不可先行排序数组的去重操作,利用哈希表记录是否出现过。利用哈希表对每一层的元素进行记录,如果存在表示之前使用过,就不用再遍历这个分支了
//至少从第二层开始记录
//遇到比最后一个小的就要返回
class Solution {
private:
vector<vector<int>> res;
vector<int> path;
public:
void getSeq(vector<int>& nums, int startIndex)
{
if(path.size()>1)
{
res.push_back(path);
}
if(startIndex == nums.size())
{
return;
}
unordered_set<int> checkset; // 对每一层的元素使用情况进行统计, 可以优化为数组
for(int i = startIndex;i<nums.size();i++)
{
//当路径数组不为空,要添加元素小于路径最后一个元素,这个元素已经被搜寻过,就跳过不插入
if(!path.empty() && nums[i]<path.back() || checkset.find(nums[i])!=checkset.end())
{
continue;
}
checkset.insert(nums[i]);
path.push_back(nums[i]);
getSeq(nums,i+1);
path.pop_back();
}
}
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
getSeq(nums,0);
return res;
}
};
46.全排列
文档讲解:代码随想录
视频讲解: 组合与排列的区别,回溯算法求解的时候,有何不同?| LeetCode:46.全排列
状态
排列与顺序相关,所以之前在组合中使用的决定下一层开始位置的元素就不需要了,因为每次都是从0开始,唯一需要注意的是,上一层用过的元素,下一层应当去掉,所以我们使用一个used数组,在组合去重问题中,我们是考虑同一层,现在需要考虑是同一个树枝,如果其在下一层为1,那么说明上一层用过,应当跳过。
//排列:考虑顺序,startIndex永远从0开始
class Solution {
private:
vector<vector<int>> res;
vector<int> path;
public:
void getPer(vector<int>& nums,vector<int> used)
{
if(path.size() == nums.size())
{
res.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]);
getPer(nums,used);
path.pop_back();
used[i] = 0;
}
return ;
}
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<int> used(nums.size());
getPer(nums,used);
return res;
}
};
47.全排列II
文档讲解:代码随想录
视频讲解: 回溯算法求解全排列,如何去重?| LeetCode:47.全排列 II
状态
这道题又需要去重,相当于同一层去除之前用过的元素,同一树枝去除上一层的元素
class Solution {
private:
vector<vector<int>> res;
vector<int> path;
public:
void getPer(vector<int>& nums,vector<int> used)
{
if(path.size() == nums.size())
{
res.push_back(path);
return;
}
for(int i = 0;i<nums.size();i++)
{
//同一层
if(i>0 && used[i-1] == 0 && nums[i-1] == nums[i])
{
continue;
}
//同一树枝
if(used[i] == 1)
{
continue;
}
used[i] = 1;
path.push_back(nums[i]);
getPer(nums,used);
path.pop_back();
used[i]=0;
}
return;
}
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<int> used(nums.size());
sort(nums.begin(),nums.end());
getPer(nums,used);
return res;
}
};