思路一:
1.首先我们确定一个结果集合res和一个临时路径集合temp。
2.遍历数组的每个元素,对于每个元素,有取和不取两种选择,使得对应的temp不同,当我们遍历完最后一个元素时,需要将temp加入res当中。
3.由于题目要求是递增序列,所以在取之前我们需要判断当前元素是否大于等于temp当中最后一个元素,如果不满足,则不取当前元素,然后继续递归遍历下一个元素。
4.如果满足的话,我们将当前元素加入temp当中,然后递归遍历下一个元素。在递归回溯之后,我们还需要考虑当前元素不取的情况,所以我们需要将当前元素从temp当中弹出,如果当前元素是不等于temp当中的最后一个元素,那么递归继续遍历下一个元素;反之,我们不需要进行考虑当前元素不取的情况。
5.如果出现当前元素nums[i]和temp最后一个元素last相等的情况,我们取舍的考虑应该有4种情况:
- last和nums[i]都取
- last取,nums[i]不取
- last不取,nums[i]取
- last和nums[i]都不取
6.对于第二第三种情况属于重复,需要舍弃一种,舍弃的办法就是,如果nums[i]==last,那么递归继续遍历下一个元素;反之,我们不需要进行考虑nums[i]不取的情况。
代码一:
class Solution {
public:
vector<int> temp;
vector<vector<int>> res;
void backtrack(int start,vector<int>& nums)
{
if(start>=nums.size())
{
if(temp.size()>=2)
res.push_back(temp);
return;
}
if(temp.empty())
{
temp.push_back(nums[start]);
backtrack(start+1,nums);
temp.pop_back();
backtrack(start+1,nums);
}
else if(!temp.empty()&&nums[start]>=temp.back())
{
temp.push_back(nums[start]);
backtrack(start+1,nums);
temp.pop_back();
if(nums[start]!=temp.back())
{
backtrack(start+1,nums);
}
}
else
{
backtrack(start+1,nums);
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
backtrack(0,nums);
return res;
}
};
代码二 :
class Solution {
public:
vector<int> temp;
vector<vector<int>> res;
void backtrack(int start,vector<int>& nums)
{
unordered_set<int> uset;
if(start>=nums.size())
{
return;
}
for(int i=start;i<nums.size();i++)
{
if(temp.empty()&&uset.count(nums[i])==0)
{
uset.insert(nums[i]);
temp.push_back(nums[i]);
backtrack(i+1,nums);
temp.pop_back();
}
else if(!temp.empty()&&nums[i]>=temp.back()&&uset.count(nums[i])==0)
{
uset.insert(nums[i]);
temp.push_back(nums[i]);
res.push_back(temp);
backtrack(i+1,nums);
temp.pop_back();
}
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
backtrack(0,nums);
return res;
}
};