题目
给你一个整数数组 nums ,请你找出 nums 子集 按位或 可能得到的 最大值 ,并返回按位或能得到最大值的 不同非空子集的数目 。
如果数组 a 可以由数组 b 删除一些元素(或不删除)得到,则认为数组 a 是数组 b 的一个 子集 。如果选中的元素下标位置不一样,则认为两个子集 不同 。
对数组 a 执行 按位或 ,结果等于 a[0] OR a[1] OR … OR a[a.length - 1](下标从 0 开始)。
链接:https://leetcode-cn.com/problems/count-number-of-maximum-bitwise-or-subsets
思路
位运算
子集的数目为2的n次方,可以从两个角度理解这个事情
第一个角度,数组的每个元素可以取或者不取,所以为2的n次方
第二个角度,可以选0个,1个,…n个,根据二项式定理,也为2的n次方
方法一直接使用for循环,枚举所有可能,利用bitset转成数组
方法二使用dfs,减少了重复的计算
代码
方法一
class Solution {
public:
int countMaxOrSubsets(vector<int>& nums) {
int len=nums.size();
int max_v=0;
int ans=0;
for(int i=0;i<1<<len;i++){
bitset<16> bt(i);
int res=0;
for(int j=0;j<len;j++){
if(bt[j]) res|=nums[j];
}
if(max_v<res){
max_v=res;
ans=1;
}else if(max_v==res)
ans++;
}
return ans;
}
};
方法二
class Solution {
public:
int max_v=0;
int ans=0;
vector<int> nums;
int countMaxOrSubsets(vector<int>& nums) {
this->nums=nums;
dfs(0,0);
return ans;
}
void dfs(int index,int res){
// 先递归,后访问,统一处理
if(res>max_v){
max_v=res;
ans=1;
}else if(max_v==res)
ans++;
for(int i=index;i<nums.size();i++){ // 此处使用备份方式
int temp=res|nums[i];
dfs(i+1,temp);
}
}
};