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

题目

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

题目大意

给你一个整数数组 nums ,请你找出 nums 子集 按位或 可能得到的 最大值 ,并返回按位或能得到最大值的 不同非空子集的数目

如果数组 a 可以由数组 b 删除一些元素(或不删除)得到,则认为数组 a 是数组 b 的一个 子集 。如果选中的元素下标位置不一样,则认为两个子集 不同

对数组 a 执行 按位或 ,结果等于 a[0] | a[1]| ...| a[a.length - 1](下标从 0 开始)。

样例

image-20220315151535746

数据规模

image-20220315151547906

思路

看到这题第一想法就是对于每个元素nums[i]选还是不选。再看数据范围1<=nums.length<=16。那肯定就是直接搜索,时间复杂度O(2^n)

定义一个计数器unordered_map<int,int>mp;用于记录每种结果的数量;定义maxx记录子集的最大按位或。

函数void dfs(int x,int w,vector<int>& nums)x表示当前枚举第x个元素(从0开始),一旦x=nums.length就可以停止往下递归,统计答案,累加结果。每次对于第x个元素,可以选或者不选,相应的累计按位或的值ww|nums[i]w

最后子集的最大按位或为maxx,所求的答案就是mp[maxx]

代码

// short int long float double bool char string void
// array vector stack queue auto const operator
// class public private static friend extern 
// sizeof new delete return cout cin memset malloc
// relloc size length memset malloc relloc size length
// for while if else switch case continue break system
// endl reverse sort swap substr begin end iterator
// namespace include define NULL nullptr exit equals 
// index col row arr err left right ans res vec que sta
// state flag ch str max min default charray std
// maxn minn INT_MAX INT_MIN push_back insert
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+50;//注意修改大小
long long read(){long long x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f;}
ll qpow(ll x,ll q,ll Mod){ll ans=1;while(q){if(q&1)ans=ans*x%Mod;q>>=1;x=(x*x)%Mod;}return ans%Mod;}

class Solution {
public:
	unordered_map<int,int>mp;
	int maxx;
	void dfs(int x,int w,vector<int>& nums){
		if(x==nums.size()){
			mp[w]++;
			maxx=max(maxx,w);
			return;
		}
		dfs(x+1,w|nums[x],nums);
		dfs(x+1,w,nums);
	}
    int countMaxOrSubsets(vector<int>& nums) {
		dfs(0,0,nums);
		return mp[maxx];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Phoenix_ZengHao

创作不易,能否打赏一瓶饮料?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值