Leetcode Link: 6127. 优质数对的数目 - 力扣(LeetCode)
题目
给你一个下标从 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) 也可以是优质数对。

解法一
思路: 仔细思考本题
设函数 c(x) 的输出为数字 x 二进制表示下的 1 的数量
本题题目:c(n1 AND n2) + c(n1 OR n2) >=k 的 n1 和 n2 组成的数对为”优质数对”
通过草稿演算,我们有
c(n1 AND n2) + c(n1 OR n2) = c(n1) + c(n2)
故本题只需要考虑两个数字的 1 数量的总和即可。
- 去重(这一步在任何题目里都要先考虑,重复究竟对于结果有没有影响)
- 统计所有数字 1 的个数
- 按照所含有 1 的数量对去重后的结果进行分组
- 每两组比较,若含有1的总数>k,则这两组中任意两对都是优质数组
题解:
class Solution:
def countExcellentPairs(self, nums: List[int], k: int) -> int:
nums = set(nums) #去重
cnt = [n.bit_count() for n in nums] # 统计1的个数
counter = Counter(cnt) #按照1的个数分组,其实就是计数 {num of 1: how many numbers}
res = 0
# 两组两组比较
for k1, v1 in counter.items():
for k2, v2 in counter.items():
if k1 + k2 >= k:
res += (v1 * v2)
return res