当前位置:网站首页>LeetCode 2354. 优质数对的数目 二进制01表示和集合之间的转换
LeetCode 2354. 优质数对的数目 二进制01表示和集合之间的转换
2022-08-02 14:11:00 【超级码力奥】
给你一个下标从 0 开始的正整数数组 nums 和一个正整数 k 。
如果满足下述条件,则数对 (num1, num2) 是 优质数对 :
num1 和 num2 都 在数组 nums 中存在。
num1 OR num2 和 num1 AND num2 的二进制表示中值为 1 的位数之和大于等于 k ,其中 OR 是按位 或 操作,而 AND 是按位 与 操作。
返回 不同 优质数对的数目。
如果 a != c 或者 b != d ,则认为 (a, b) 和 (c, d) 是不同的两个数对。例如,(1, 2) 和 (2, 1) 不同。
注意:如果 num1 在数组中至少出现 一次 ,则满足 num1 == num2 的数对 (num1, num2) 也可以是优质数对。
示例 1:
输入:nums = [1,2,3,1], k = 3
输出:5
解释:有如下几个优质数对:
- (3, 3):(3 AND 3) 和 (3 OR 3) 的二进制表示都等于 (11) 。值为 1 的位数和等于 2 + 2 = 4 ,大于等于 k = 3 。
- (2, 3) 和 (3, 2): (2 AND 3) 的二进制表示等于 (10) ,(2 OR 3) 的二进制表示等于 (11) 。值为 1 的位数和等于 1 + 2 = 3 。
- (1, 3) 和 (3, 1): (1 AND 3) 的二进制表示等于 (01) ,(1 OR 3) 的二进制表示等于 (11) 。值为 1 的位数和等于 1 + 2 = 3 。
所以优质数对的数目是 5 。
示例 2:
输入:nums = [5,1,1], k = 10
输出:0
解释:该数组中不存在优质数对。
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 109
1 <= k <= 60
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/number-of-excellent-pairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
总而言之
这道题的关键点就在于题目中定义的那个运算。为什么要定义那样的运算?这种运算有啥性质?
首先,与运算和或运算不会让总的1的个数减少。两个数与加上两个数或就等于
(2, 3) 和 (3, 2): (2 AND 3) 的二进制表示等于 (10) ,(2 OR 3) 的二进制表示等于 (11) 。值为 1 的位数和等于 1 + 2 = 3 。
例如 x=110x=110,y=011y=011,只统计一次的部分为 x’=100x
′
=100,y’=001y
′
=001,统计了两次的部分为 x&y=010x&y=010。我们可以直接把 010010 重新分配到 x’x
′
和 y’y
′
上,这样又得到了 xx 和 yy。
记 c(x)c(x) 为 xx 的二进制表示中的 11 的个数,则有如下等式:
c(x|y)+c(x&y)=c(x)+c(y)
c(x∣y)+c(x&y)=c(x)+c(y)
另外一种思路是把二进制数看成集合,根据容斥原理 |A∪B∣=∣A∣+∣B∣−∣A∩B∣,得
∣A∪B∣+∣A∩B∣=∣A∣+∣B∣
现在就转换成找两个数,这俩数中二进制表示里边1的个数之和大于等于k就行了。但是数太多了,总不能暴力,这样时间复杂度10^10了。
考虑到数最大10^9有不超过30个1。因此,可以开一个cnt[30],cnt[i]就表示二进制表示中1的个数为i的数有多少个。
注意:
自己和自己也可以,俩数换换位置也可以,但是记得给原来的数组去重,否则会多次统计,影响正确。
class Solution {
public:
long long countExcellentPairs(vector<int>& nums, int k) {
typedef long long LL;
// 去重
sort(nums.begin(), nums.end());
// unique函数会将数组里连续相同的数删掉只剩一个,然后返回最后位置的下一个位置,然后将这个位置到最后一个位置删掉就可以了
nums.erase(unique(nums.begin(), nums.end()), nums.end());
// 初始化记录1的个数的数组
int cnt[30] = {
0};
for(auto x: nums){
int s = 0;
while(x) s += x & 1, x >>= 1;
cnt[s] ++;
}
// 遍历
LL res = 0;
for(int i = 0; i < 30; i ++)
for(int j = 0; j < 30; j ++)
if(i + j >= k)
res += (LL)cnt[i] * cnt[j];
return res;
}
};
Python:
class Solution:
def countExcellentPairs(self, nums: List[int], k: int) -> int:
# 使用Counter统计, bit_count返回有几个1,set对原来的数组去重
cnt = Counter(x.bit_count() for x in set(nums))
ans = 0
# cnt是个字典,就是cnt[30]
for cx, ccx in cnt.items():
for cy, ccy in cnt.items():
if cx + cy >= k:
ans += ccx * ccy
return ans
复杂度分析
时间复杂度:O(n+U^2) 其中 n为 nums 的长度,U为不同的 c(nums[i]) 的个数,不超过 30。
空间复杂度:O(n+U)。
后缀和优化
# 后缀和优化,因为cx + cy >= k, 当遍历到cy之后, cy - 30的都是可以的了
cnt = [0] * 30
for x in set(nums):
cnt[x.bit_count()] += 1
ans = 0
# 先把cnt[k] 到 cnt[30] 求和
s = sum(cnt[k:])
# 从前往后遍历
for cx, ccx in enumerate(cnt):
ans += ccx * s
# 当前遍历到的索引为cx, 那么末尾的为k - cx
if 0 <= k - 1 - cx < 30:
# 处理后缀和
s += cnt[k - 1 - cx]
return ans
边栏推荐
- Masters and Masters
- MATLAB制作简易小动画入门详解
- Do Windows 10 computers need antivirus software installed?
- DP1332E刷卡芯片支持NFC内置mcu智能楼宇/终端poss机/智能门锁
- 开心一下,9/28名场面合集
- win10系统更新错误代码0x80244022怎么办
- 使用npx -p @storybook/cli sb init安装失败,手把手搭建专属的storybook
- Installation and configuration of Spark and related ecological components - quick recall
- MATLAB绘图函数fplot详解
- Use libcurl to upload the image of Opencv Mat to the file server, based on two methods of post request and ftp protocol
猜你喜欢
A clean start Windows 7?How to load only the basic service start Windows 7 system
倍增和稀疏表
Mysql的锁
Happy, 9/28 scene collection
Summarize computer network super comprehensive test questions
Win10 cannot directly use photo viewer to open the picture
总结计算机网络超全面试题
如何用硬币模拟1/3的概率,以及任意概率?
Win11 system cannot find dll file how to fix
golang之GMP调度模型
随机推荐
Open the door of power and electricity "Circuit" (2): Power Calculation and Judgment
SQL的通用语法和使用说明(图文)
Publish module to NPM should be how to operate?Solutions to problems and mistake
Use libcurl to upload the image of Opencv Mat to the file server, based on two methods of post request and ftp protocol
一篇文章彻底理解Redis的持久化:RDB、AOF
使用 腾讯云搭建一个个人博客
What should I do if the Win10 system sets the application identity to automatically prompt for access denied?
日常-笔记
发布模块到npm应该怎么操作?及错误问题解决方案
How to set the win10 taskbar does not merge icons
MATLAB绘图函数ezplot入门详解
Golang 垃圾回收机制详解
Mysql之MVCC
3. User upload avatar
Installation and configuration of Spark and related ecological components - quick recall
LeetCode2 电话号码的字母组合
Network Security Packet Capture
轻量化AlphaPose
推开机电的大门《电路》(二):功率计算与判断
pygame图像连续旋转