491. 递增子序列(题目链接:力扣)
思路:子集问题,需要收集整颗树的节点(根据题目要求元素的个数至少要两个,所以要收集深度大于等于2的节点),这题有点小坑,就是不能将数组排序,因此无法用startIndex+1的方式来进行层内的去重(但是仍需要startIndex+1的方式来保证节点是数组从前往后遍历的)。所以每层递归需要额外声明一个unordered_set集合,用来记录本层用过了的数值,保证层内所有节点数值不重复。
vector> result;
void backtracking(const vector& nums, vector& tmpSum, int startIndex){
if(tmpSum.size() > 1){
result.push_back(tmpSum);
}
unordered_set uset;
for(int i=startIndex; i> findSubsequences(vector& nums) {
vector tmpSum;
backtracking(nums, tmpSum, 0);
return result;
}
46. 全排列(题目链接:力扣)
思路:全排列问题,收集的是树的所有叶子节点。因为数组不含重复元素,因此每次添加只需判断该元素是否已经使用过,因此只需定义一个数组vector
vector> result;
void backtracking(vector& nums, vector& tmpSum, vector& uset){
if(tmpSum.size() == nums.size()){
result.push_back(tmpSum);
return;
}
for(int i=0; i> permute(vector& nums) {
vector tmpSum;
vector uset(nums.size(), false);
backtracking(nums, tmpSum, uset);
return result;
}
47. 全排列 II(题目链接:力扣)
思路:同上题,题解依然是树的所有叶子节点。但是数组内有重复元素,层内需要保证每个节点的值是不一样的。同一路径需要保证所用到的元素是唯一的(数值可以相等,因为数组有相同值元素,但是下标唯一),因此仍然需要vector
vector> result;
void backtracking(vector& nums, vector& tmpSum, vector& uset){
if(tmpSum.size() == nums.size()){
result.push_back(tmpSum);
return;
}
unordered_set isUse;
for(int i=0; i> permuteUnique(vector& nums) {
vector tmpSum;
vector uset(nums.size(), false);
backtracking(nums, tmpSum, uset);
return result;
}
其实还有一种不用unordered_set
vector> result;
void backtracking(vector& nums, vector& tmpSum, vector& uset){
if(tmpSum.size() == nums.size()){
result.push_back(tmpSum);
return;
}
for(int i=0; i0 && nums[i]==nums[i-1] && uset[i-1]==false) continue;
if(uset[i]==false){
uset[i] = true;
tmpSum.push_back(nums[i]);
backtracking(nums, tmpSum, uset);
tmpSum.pop_back();
uset[i] = false;
}
}
}
vector> permuteUnique(vector& nums) {
sort(nums.begin(), nums.end());
vector tmpSum;
vector uset(nums.size(), false);
backtracking(nums, tmpSum, uset);
return result;
}