LeetCode/子集、组合
一 . 子集
给你一个整数数组 nums ,数组中的元素 互不相同,返回该数组所有可能的子集
1. 回溯法
对每个数做选择,放入当前位,同时固定访问顺序,只访问下标更大的数,避免重复
回溯法
class Solution {
public:
vector<vector<int>> res;
vector<int> temp;
vector<vector<int>> subsets(vector<int>& nums) {
backtrack(nums,0);
return res;
}
void backtrack(vector<int>& nums,int index){
res.push_back(temp);
for(int i=index;i<nums.size();i++){
temp.push_back(nums[i]);
backtrack(nums,i+1);
temp.pop_back();
}
}
};
2. 二进制状态枚举
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
int n = nums.size();
vector<vector<int>> res;
for(int mask=0;mask<1<<n;mask++){//遍历所有状态
vector<int> temp;
for(int i=0;i<n;i++)//遍历状态每一位
if(mask>>i&1) temp.push_back(nums[i]);
res.push_back(temp);
}
return res;
}
};
二. 组合
给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合
1. 回溯法
回溯法
class Solution {
public:
vector<vector<int>> res;
vector<int> cur;
vector<vector<int>> combine(int n, int k) {
trackback(1,n,k);
return res;
}
void trackback(int val,int n,int k){
if(cur.size()==k){ //一个满足条件的结果
res.push_back(cur);
return;
}
for(int i = val;i<=n;i++){ //遍历所有待选值
if(n-i+1<k-cur.size()) break;//剪枝条件,后面元素不足
cur.push_back(i);
trackback(i+1,n,k);
cur.pop_back();
}
}
};
2. 二进制状态枚举
class Solution {
public:
vector<vector<int>> combine(int n, int k) {
vector<vector<int>> res;
vector<int> temp;
for (int mask = 0; mask < (1 << n); mask++) //遍历所有状态
{
if (k == numOf1(mask))
{
temp.clear();
for (int i = 0; i < n; ++i)
if (mask & (1 << i))
temp.emplace_back(i+1);
res.emplace_back(temp);
}
}
return res;
}
int numOf1(int num)
{
int result = 0;
while (num){
num &= (num - 1);
result++;
}
return result;
}
};