统计按位或能得到最大值的子集数目

题目

给你一个整数数组 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);
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值