分享|从集合论到位运算,常见位运算技巧分类总结! - 力扣(LeetCode)
可以使用位运算的题目
class Solution {
public:
vector<vector<int>> subsets(vector<int>& nums) {
vector<vector<int>>res;
res.push_back(nums);
for(int i=0;i<nums.size();i++){
nums[i]+=10;
}
int m=0;
for(int i=0;i<nums.size();i++)
{
m=m+(1<<nums[i]);
}
int sub=m;
do{
sub=(sub-1)&m;
int w=sub;
if(w!=m)
{
int i=0;
vector<int>s;
while(w)
{
if(w&1)
{
s.push_back(i-10);
}
i++;
w=w>>1;
}
res.push_back(s);
}
}while(sub!=m);
return res;
}
};
//dfs
class Solution {
public:
vector<vector<int>>res;
int vis[25];
void dfs(int n,int k,vector<int> &ve,int step,int st)
{
if(step==k)
{
res.push_back(ve);
return;
}
for(int i=st;i<=n;i++)
{
if(n-i+1<k-(step+1)+1)
{
return;
}
if(!vis[i])
{
ve[step]=i;
vis[i]=1;
dfs(n,k,ve,step+1,i+1);
vis[i]=0;
}
}
}
vector<vector<int>> combine(int n, int k) {
memset(vis,0,sizeof(vis));
vector<int>ve(k,0);
dfs(n,k,ve,0,1);
return res;
}
};
//位运算
class Solution {
public:
vector<vector<int>> combine(int n, int k) {
int m=0;
vector<vector<int>>res;
for(int i=1;i<=n;i++)
{
m=m+(1<<i);
}
int sub=m;
do{
sub=(sub-1)&m;
int w=sub;
vector<int>s;
int i=0;
while(w)
{
if(w&1)
{
s.push_back(i);
}
i++;
w=w>>1;
}
if(s.size()==k)
{
res.push_back(s);
}
}while(sub!=m);
return res;
}
};
状压DP
2172. 数组的最大与和
class Solution {
public:
int maximumANDSum(vector<int>& nums, int numSlots) {
int ans=0;
vector<int>f(1<<(numSlots*2));
f[0]=0;
for(int i=0;i<f.size();i++)
{
int c=__builtin_popcount(i);
if(c>=nums.size()) continue;
for(int j=0;j<numSlots*2;j++)
{
if((i &(1<<j))==0){
int s=i|1<<j;
f[s]=max(f[s],f[i]+((j/2+1)&nums[c]));
ans=max(ans,f[s]);
}
}
}
return ans;
}
};
class Solution {
public:
int minimumXORSum(vector<int>& nums1, vector<int>& nums2) {
vector<int>f(1<<nums1.size(),0x3f3f3f3f);
f[0]=0;
for(int i=0;i<(1<<nums2.size());i++){
int c=__builtin_popcount(i);
for(int j=0;j<nums2.size();j++)
{
if(i&(1<<j)){
f[i]=min(f[i],f[i^(1<<j)]+(nums1[c-1]^nums2[j]));
}
}
}
return f[(1<<nums2.size())-1];
}
};
1125. 最小的必要团队
class Solution {
public:
vector<int> smallestSufficientTeam(vector<string>& req_skills, vector<vector<string>>& people) {
map<string,int>mp;
for(int i=0;i<req_skills.size();i++){
mp[req_skills[i]]=i;
}
int n=req_skills.size();
int m=people.size();
vector<vector<int>>dp(1<<n);
for(int i=0;i<m;i++){
int cur_skill=0;
for(int j=0;j<people[i].size();j++)
{
cur_skill =cur_skill | (1<<mp[people[i][j]]);
}
for(int pre=0;pre<(1<<n);pre++){
if(pre>0 && dp[pre].size()==0){
continue;
}
int com= cur_skill | pre;
if(com==pre) continue;
if(dp[com].size()==0 || dp[pre].size()+1<dp[com].size()){
dp[com]=dp[pre];
dp[com].push_back(i);
}
}
}
return dp[(1<<n)-1];
}
};
2305. 公平分发饼干![](https://img-blog.csdnimg.cn/7ee401bf203e427fb281979d33950800.png)
class Solution {
public:
int distributeCookies(vector<int> &cookies, int k) {
int n = cookies.size();
vector<int> sum(1 << n);
for (int i = 0; i < n; i++)
for (int j = 0, bit = 1 << i; j < bit; j++)
sum[bit | j] = sum[j] + cookies[i];
vector<int> f(sum);
for (int i = 1; i < k; i++) {
for (int j = (1 << n) - 1; j; j--) {
for (int s = j; s; s = (s - 1) & j) {
f[j] = min(f[j], max(f[j ^ s], sum[s]));
}
}
}
return f.back();
}
};