思路:定义非递减序列函数以及path的长度大于1作为结束判断的条件,用哈希set去重,重点是res插入path路径时,不要用return,因为要取树上的所有节点
代码:
class Solution {
private:
vector<vector<int>> res;
vector<int> path;
bool issort(vector<int>& nums)
{
for(int i = nums.size()-1;i > 0;i--)
{
if(nums[i] < nums[i-1]) return false;
}
return true;
}
void backtrace(vector<int>& nums,int index)
{
if(path.size() > 1 && issort(path)) res.push_back(path);
unordered_set<int> set;
for(int i = index;i < nums.size();i++)
{
if(set.find(nums[i]) != set.end()) continue;
set.insert(nums[i]);
path.push_back(nums[i]);
backtrace(nums,i+1);
path.pop_back();
}
}
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
backtrace(nums,0);
return res;
}
};
思路:需要注意使用vector<bool> sort来存储某个元素是否被选择过,然后在回溯过程中,每次插入到path前需要设置其为true,表示马上会选择该值;然后在回溯时设为false,表示该值未被选择,后续可以继续使用。
代码:
class Solution {
private:
vector<vector<int>> res;
vector<int> path;
void backtrace(vector<int>& nums,int index,vector<bool>& sort)
{
if(nums.size() == path.size())
{
res.push_back(path);
return;
}
for(int i = index;i < nums.size();i++)
{
if(!sort[i])
{
sort[i] = true;//nums[i]被选择过了
path.push_back(nums[i]);//插入
backtrace(nums,index,sort);
sort[i] = false;//回溯,以便后续的nums[i]仍然可以被选择
path.pop_back();
}
}
}
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<bool> sort(nums.size(),false);
backtrace(nums,0,sort);
return res;
}
};
思路:和上题不同的是数组会出现重复的元素,因此结果需要去重,用哈希set存储被选择过的数组,如果被使用过则跳过,否则执行插入以及bool操作
代码:
class Solution {
private:
vector<vector<int>> res;
vector<int> path;
void backtrace(vector<int>& nums,vector<bool>& sort )
{
if(nums.size() == path.size())
{
res.push_back(path);
return;
}
unordered_set<int> set;
for(int i = 0;i < nums.size();i++)
{
if(!sort[i])
{
if(set.find(nums[i]) != set.end()) continue;
set.insert(nums[i]);
sort[i] = true;
path.push_back(nums[i]);
backtrace(nums,sort);
sort[i] = false;
path.pop_back();
}
}
}
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<bool> sort(nums.size(),false);
backtrace(nums,sort);
return res;
}
};