491非递减子序列 1.递归三部曲 2.去重的关键要素
class Solution {
private:
vector<int> tmp;
vector<vector<int>> result;
void backtracking(vector<int>& nums,int index){
//底层递归
// 递归终止条件:遍历到数组末尾,直接返回
if (tmp.size() >= 2) {
result.push_back(tmp);
}
// 递归终止条件:遍历到数组末尾,直接返回
if (index == nums.size()) {
return;
}
// 单层递归逻辑:从index开始遍历,选取元素构建子集
// 关键:used定义在本层递归开头,记录本层已使用过的元素(去重)
unordered_set<int> used;
// 单层递归逻辑:从index开始遍历
for (int i = index; i < nums.size(); i++) {
// 两个跳过条件(满足其一则跳过):
// 1. 子序列非空且当前元素 < 最后一个元素(破坏递增)
// 2. 本层已使用过当前元素(去重)
if ((!tmp.empty() && nums[i] < tmp.back()) || (used.find(nums[i]) != used.end())) {
continue;
}
used.insert(nums[i]); // 标记本层已使用该元素
tmp.push_back(nums[i]); // 选择当前元素
backtracking(nums, i + 1); // 递归到下一层
tmp.pop_back(); // 回溯:撤销选择
}
}
public:
vector<vector<int>> findSubsequences(vector<int>& nums) {
tmp.clear();
result.clear();
backtracking(nums,0);
return result;
}
};
46.全排列 1.递归三部曲 2.需要引入used数组来对使用过的字符进行标记
class Solution {
//递归三部曲
private:
vector<vector<int>> result;//存储结果
vector<int> tmp;
void backtracking(vector<int>& nums,vector<bool>& used){
if(tmp.size()==nums.size()){
result.push_back(tmp);
return;
}
for(int i=0;i<nums.size();i++){
if(used[i]==true) continue;//该数字被使用
used[i]=true;//标记已被使用
tmp.push_back(nums[i]);
backtracking(nums,used);
tmp.pop_back();
used[i]=false;
}
}
public:
vector<vector<int>> permute(vector<int>& nums) {
result.clear();
tmp.clear();
vector<bool> used(nums.size(), false);
backtracking(nums,used);
return result;
}
};
47 全排列Ⅱ 1.重点在于去重!!!
class Solution {
//递归三部曲
private:
vector<vector<int>> result;//存储结果
vector<int> tmp;
void backtracking(vector<int>& nums,vector<bool>& used){
if(tmp.size()==nums.size()){
result.push_back(tmp);
return;
}
for(int i=0;i<nums.size();i++){
if (used[i] == true || (i > 0 && nums[i] == nums[i-1] && !used[i-1])) {
continue;
}
tmp.push_back(nums[i]);
used[i]=true;
backtracking(nums,used);
tmp.pop_back();
used[i]=false;
}
}
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
result.clear();
tmp.clear();
sort(nums.begin(),nums.end());//去重之前对原数组进行排序
vector<bool> used(nums.size(), false);
backtracking(nums,used);
return result;
}
};