1.非递减子序列(递增子序列)
思路:
1.不可以对数组进行排序。因为排序后会改变数组的顺序结构,得到错误的答案。
2.数组中存在相同的元素。因此,需要进行去重操作。
3.本题的去重操作不可以用used数组,因为利用used去标记使用过的元素,执行去重操作时,需要对数组进行排序。因此,本体采用set去重。
4.两种去重方法:used数组去重 和 set去重。
class Solution {
public:
vector<int> path;
vector<vector<int>> result;
void backtracking(vector<int>& nums,int startIndex){
if(path.size() > 1){
result.push_back(path);
}
unordered_set<int> uset; // 使用set对本层元素进行去重
for(int i = startIndex;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]);
backtracking(nums,i + 1);
path.pop_back();
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
path.clear();
result.clear();
backtracking(nums,0);
return result;
}
};
2.全排列
思路:
1.数组中不存在重复的元素,所以不需要去重操作。
2.处理排列问题就不用使用startIndex了。
3.但排列问题需要一个used数组,标记已经选择的元素。
4.叶子结点得到结果。
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++){
if(used[i] == true) continue;
path.push_back(nums[i]);
used[i] = true;
backtracking(nums,used);
path.pop_back();
used[i] = false;
}
return ;
}
vector<vector<int>> permute(vector<int>& nums) {
path.clear();
result.clear();
vector<bool> used(nums.size(),false);
backtracking(nums,used);
return result;
}
};
3.全排列2
思路:
1.数组中存在重复的元素,但是得到的解集中不可以出现重复数组。所以,需要去重操作。
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++){
if(i > 0 && nums[i] == nums[i - 1] && used[i - 1] == false) continue;
if(used[i] == true) continue;
used[i] = true;
path.push_back(nums[i]);
backtracking(nums,used);
used[i] = false;
path.pop_back();
}
return;
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
path.clear();
result.clear();
vector<bool> used(nums.size(),false);
sort(nums.begin(),nums.end()); //排序
backtracking(nums,used);
return result;
}
};