90. 子集 II
题目地址:90. 子集 II - 力扣(LeetCode)
题解思路:子集 + 去重
时间复杂度:O(n * 2^n)
空间复杂度:O(n)
代码:
class Solution {
public:
vector<vector<int>>ret;
vector<int>v;
void backtrack(vector<int>&nums, int start){
ret.push_back(v); // 子集
if(start >= nums.size()){
return ;
}
int size = nums.size();
for(int i = start; i < size; i++){
// 重复的子集
if(i > start && nums[i] == nums[i - 1]){
continue;
}
v.push_back(nums[i]);
backtrack(nums, i + 1);
v.pop_back();
}
}
vector<vector<int>> subsetsWithDup(vector<int>& nums) {
sort(nums.begin(), nums.end());
backtrack(nums, 0);
return ret;
}
};
491. 非递减子序列
题目地址:491. 非递减子序列 - 力扣(LeetCode)
题解思路:子集,递增,去重,元素个数>2
时间复杂度:O(n * 2^n)
空间复杂度:O(n)
代码:
class Solution {
public:
vector<vector<int>>ret;
vector<int>v;
void backtrack(vector<int>& nums, int start){
if(v.size() > 1){
ret.push_back(v);
}
if(start >= nums.size()){
return ;
}
// 同一层
unordered_set<int>st;
int size = nums.size();
for(int i = start; i < size; ++i){
// 递增
if(!v.empty() && nums[i] < v.back()){
continue;
}
// 不重复
if(st.find(nums[i]) == st.end()){
st.insert(nums[i]);
v.push_back(nums[i]);
backtrack(nums, i + 1);
v.pop_back();
}
}
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
// 子集,递增
backtrack(nums, 0);
return ret;
}
};
46. 全排列
题目地址:46. 全排列 - 力扣(LeetCode)
题解思路:回溯,注意遍历过的元素不可以再次遍历
时间复杂度:O(n!)
空间复杂度:O(n)
代码:
class Solution {
public:
vector<vector<int>>ret;
vector<int>v;
unordered_set<int>uset;
void backtrack(vector<int>& nums){
if(v.size() == nums.size()){
ret.push_back(v);
return ;
}
for(auto i : nums){
if(uset.find(i) == uset.end()){
uset.insert(i);
v.push_back(i);
backtrack(nums);
v.pop_back();
uset.erase(i);
}
}
}
vector<vector<int>> permute(vector<int>& nums) {
backtrack(nums);
return ret;
}
};
47. 全排列 II
题目地址:47. 全排列 II - 力扣(LeetCode)
题解思路:全排列,去重
时间复杂度:O(n * n!)
空间复杂度:O(n)
代码:
class Solution {
public:
vector<vector<int>>ret;
vector<int>v;
void backtrack(vector<int>& nums, vector<int>& used_id){
if(nums.size() == v.size()){
ret.push_back(v);
return ;
}
unordered_set<int>cut;
int size = nums.size();
for(int i = 0; i < size; i++){
if(used_id[i] == 0){ // 同一分支
if(cut.find(nums[i]) == cut.end()){
// 同层
cut.insert(nums[i]);
used_id[i] = 1;
v.push_back(nums[i]);
backtrack(nums, used_id);
v.pop_back();
used_id[i] = 0;
}
}
}
}
vector<vector<int>> permuteUnique(vector<int>& nums) {
// 同一层不能重复
vector<int>used_id(nums.size(), 0);
backtrack(nums, used_id);
return ret;
}
};