LeetCode。491递增子序列
题目链接:491. 递增子序列 - 力扣(LeetCode)
思路:
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void backt(vector<int>& nums,int start) {
if(path.size() > 1) result.push_back(path);//不能加return,因为取树上所有节点
unordered_set<int> uset;//用set对本层去重
for(int i = start; i < nums.size(); i++) {
if((!path.empty() && nums[i] < path.back()) || uset.find(nums[i]) != uset.end())
continue;
uset.insert(nums[i]);//记录这个元素在本层用过了,本层后面不能再用了
path.push_back(nums[i]);
backt(nums,i + 1);
path.pop_back();
}
return ;
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
backt(nums,0);
return result;
}
};
LeetCode46.全排列
题目链接:491. 递增子序列 - 力扣(LeetCode)
思路:
用一个used数组来看哪些数被取过,就不取了.
排列问题的不同:
- 每层都是从0开始搜索而不是startIndex
- 需要used数组记录path里都放了哪些元素了
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void backt(vector<int>& nums,vector<bool>& used) {
if(path.size() == nums.size()) {
result.push_back(path);
return ;
}
for(int i = 0;i < nums.size();i++) {
if(used[i] == true) continue;
path.push_back(nums[i]);
used[i] = true;
backt(nums,used);
used[i] = false;
path.pop_back();
}
}
vector<vector<int>> permute(vector<int>& nums) {
vector<bool> used(nums.size(),false);
backt(nums,used);
return result;
}
};
LeetCode47.全排列II
题目链接:
思路:
对于排列问题,树层上去重和树枝上去重,都是可以的,但是树层上去重效率更高!
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums,vector<bool>& used) {
//找到一组
if(path.size() == nums.size()) {
result.push_back(path);
return ;
}
for(int i = 0; i < nums.size();i++) {
//used[i-1] = true,说明同一树枝nums[i-1]出现过
//used[i-1] = false,说明同一树层nums[i-1]出现过,则直接跳过
if(i > 0 && nums[i] == nums[i - 1] && used[i -1] == false) continue;
if(used[i] == false) {
path.push_back(nums[i]);
used[i] = true;
backtracking(nums,used);
used[i] = false;
path.pop_back();
}
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
vector<bool> used(nums.size(),false);
sort(nums.begin(),nums.end());//去重都要排序
backtracking(nums,used);
return result;
}
};