algorithm - 数组中满足位方程的对数
问题描述
我在一次比赛中发现了这个问题。问题是:
给你一个N
非负整数数组(A1, A2, A3,..., An)和一个 integer M
。您的任务是找到(X,Y)
满足以下按位方程的无序数组元素对的数量:
2 * set_bits(X|Y) = M + set_bits(X ⊕ Y)
笔记:
set_bits(n)
表示整数n的二进制表示中的个数。X|Y
表示整数X和Y的按位或。X ⊕ Y
表示整数X和Y的按位异或。- 数组元素的无序对是对
(Ai, Aj)
,其中1 ≤ i < j ≤ N。
打印满足上述按位方程的无序数组元素对的数量。
样本输入 1:
N=4 M=2
arr = [3, 0, 4, 5]
样本输出:2
2 对是 (3,0) 和 (0,5)样本输入 2:
N=8 M=2
arr = [3, 0, 4, 5, 6, 8, 1, 8]
样本输出:9
brute force
除了解这个方程还有其他方法吗?
解决方案
如果 的时间复杂度为 ,则O(n)
存在具有时间复杂度的解。set_bits
O(1)
首先,我们将稍微改写一下条件(按位方程)。假设给定一对元素(X, Y)
。令c_01
表示X为0但Y为1c_10
的位数,表示X为1且Y为0c_11
的位数,并表示X和Y为1的位数。例如,当X=5
和Y=1
(X=101 , Y=001), c_01 = 0
, c_10 = 1
, c_11 = 1
. 现在,条件可以改写为
2 * (c_01 + c_10 + c_11) = M + (c_01 + c_10)
因为set_bits(X|Y)
等于c_01 + c_10 + c_11
和set_bits(X^Y)
等于c_01 + c_10
。我们可以将方程重新排序为
c_01 + c_10 + 2*c_11 = M
通过将右侧的术语移动到左侧。现在,意识到这一点set_bits(X) = c_10 + c_11
。将这些信息应用于我们得到的方程
c_01 + c_11 = M - set_bits(X)
现在,也意识到了set_bits(Y) = c_01 + c_11
。方程变为
set_bits(Y) = M - set_bits(X)
或者
set_bits(X) + set_bits(Y) = M
问题变成了计算对的数量,使得第一个元素中的设置位数加上第二个元素中设置的位数等于M
。set_bits
假设您可以在恒定时间内进行计算,这可以在线性时间内完成。
推荐阅读
- regex - 正则表达式搜索子字符串
- python-3.x - Python中的搜索优化
- javascript - (0 , _reactRouterDom.useHistory) 不是函数
- php - 在 WordPress 中使用 Timber/Twig 将父子类别与帖子分组并显示
- java - 当字符串的长度不同时,基数排序会错误地对字符串数组进行排序
- c# - 如何从自定义剃须刀组件公开 Blazorise TextEdit 的现有 @bind- 属性
- reactjs - 测试通过,但出现错误消息“错误:连接 ECONNREFUSED 127.0.0.1:80”
- python-3.x - 文件夹路径中三个级别的一个衬里代码
- c - 如何在 C 中将 char 数组标记为不同的 int?
- python - 可以对 Quart Schema 进行 PUT 和 GET 调用,但不能对 POST 进行调用?