计算按位 和 元素的个数等于 0 的子数组
假设我们有一个数字列表,
[7,2,9,8,6,12,109,28,14,19]
我想找到一种有效的方法来计算该列表的所有子列表,这些子列表将按位且等于零,
例如:
[2,5] # 2&5 = 0
[9,5,7,2] # 9&5&7&2 = 0
如果有人知道如何最有效地做到这一点,请告诉我
Suppose we have a list of numbers
[7,2,9,8,6,12,109,28,14,19]
I want to find a efficient way to count the all sub-list of this list which will have bitwise and equal to zero
like:
[2,5] # 2&5 = 0
[9,5,7,2] # 9&5&7&2 = 0
Let me know if anyone know how to do it most efficiently
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用滑动窗口在
O(n)
时间内完成此操作。如果我们知道索引
[L, R]
上的A
子数组的&
为零,那么我们就知道所有较大的子数组([L, R + 1]
,[L, R + 2]
,[L, R + 3]
, ...)由于以下原因,&
也将为零包含下&
的单调性。例如,从左侧计算数组的部分
&
乘积:我们将迭代滑动窗口的
右
端,同时存储最小的left
端(即最大窗口),使得A[left, left + 1, ... right]
具有非零按位&
。请注意,此左端
只能随着右端的增加而增加。要更新我们的窗口,我们需要
A[right]
获取窗口的&
(简单)&
ofA[left]
from our window (hard)为了有效地进行删除,我们将跟踪窗口中所有元素的设置位计数每个位的位置。这让我们可以在窗口中添加和删除元素,并通过测试每个设置位位置的计数是否小于窗口的长度来测试窗口的
&
是否为零。以下是示例数组上最大非零窗口的演练:
此处,非零
&
窗口大小的总和为23
。由于长度10
数组有55
个可能的子数组,因此答案为55 - 23 = 32
按位-&
- 零子数组。Python 代码:
用法示例:
注意:假设整数的最大位宽是常量。当整数可以任意大时,为了获得线性时间解决方案,您需要保留一个元计数器,它跟踪设置位的计数。
作为练习,您可以尝试推广到按位
&
等于某个可能大于零的目标t
的问题;这需要更多的工作。You can do this in
O(n)
time using a sliding window.If we know that a subarray of
A
on indices[L, R]
has an&
of zero, then we know that all larger subarrays ([L, R + 1]
,[L, R + 2]
,[L, R + 3]
, ...) will also have an&
of zero due to monotonicity of&
under inclusion.For example, computing the partial
&
products of an array from the left:We'll iterate over the
right
end of our sliding window, while storing the smallestleft
end (i.e. the largest window) such thatA[left, left + 1, ... right]
has a nonzero bitwise&
. Note that thisleft
end can only ever increase as the right end increases.To update our window, we'll need to
&
of our window withA[right]
(easy)&
ofA[left]
from our window (hard)To do removals efficiently, we'll instead track the count of set-bits for all elements in our window at each bit position. This lets us add and remove elements from our window, and test whether the
&
of our window is zero by testing whether each set bit position has a count less than the length of the window.Here's a walkthrough of the maximal nonzero windows on an example array:
Here, the sum of nonzero-
&
window sizes is23
. As a length10
array has55
possible subarrays, the answer is55 - 23 = 32
bitwise-&
-zero subarrays.Python code:
Example usage:
N.B. There's an assumption that the maximum bit-width of the integers is constant. To get a linear-time solution when integers can be arbitrarily large, you'll need to keep a meta-counter, which tracks counts of counts of set bits.
As an exercise, you can try to generalize to the problem of bitwise
&
equal to some targett
which may be greater than zero; it takes a bit more work.我们可以使用前缀和和二分查找来解决它。
步骤 1 .首先我们创建一个大小为 n*32 的数组(假设数字小于 2^32)并获取第 i 位集的前缀和。
然后应用二分查找。
代码 :
we can solve it using prefix sum and binary search.
step 1 . first we make an array of size n*32(assuming number will be less than 2^32) and take prefix sum of ith bit set.
then apply binary search.
code :