按位和子阵列的不同值

时间:2017-03-18 08:09:33

标签: algorithm

如何查找数组的按位和所有子数组的不同值的数量。(数组大小< = 1e5和数组元素< = 1e6)。 例如。 A [] = {1,2,3} 不同的值是4(1,2,3,0)。

2 个答案:

答案 0 :(得分:3)

让我们修复子阵列的右边界r。让我们的图像左边界lr开始向左移动。 and的值可以改变多少次?最多O(log(MAX_VALUE))。为什么?当我们在左边添加一个元素时,我们有两个选项:

  1. 子阵列的and值不会改变。

  2. 它改变了。在这种情况下,它的位数严格减少(因为它是前一个and值的子掩码)。

  3. 因此,我们只能考虑某些内容发生变化的l值。现在我们只需要快速找到它们。

    让我们从左到右迭代数组并存储最后一个元素的位置,该元素没有i位的所有有效i(我们可以通过迭代来更新它当前元素的所有位)。这样,我们将能够找到值快速变化的下一个位置(即,它是所有已设置位的数组中的最大值)。如果我们对排名进行排序,我们可以在O(1)找到下一个最大的位置。

    此解决方案的总时间复杂度为O(N * log(MAX_VALUE) * log(log(MAX_VALUE)))(我们迭代数组中每个元素的所有位,我们对每个元素的位置数组进行排序并对其进行迭代)。空间复杂度为O(N + MAX_VALUE)。它对于给定的约束力应该足够好。

答案 1 :(得分:1)

想象一下数字作为代表其位的列。我们将有1个水平延伸的序列。例如:

Array index:  0  1  2  3  4  5  6  7

Bit columns:  0  1  1  1  1  1  0  0
              0  0  0  1  1  1  1  1
              0  0  1  1  1  1  1  0
              1  0  0  0  1  1  0  1
              0  1  1  1  1  1  1  0

向左看,零之后的任何子阵列and的位行将继续为零,这意味着在该行之后没有更改。

让我们以索引5为例。现在将索引5中的1的水平序列排序到左边将为我们提供一种检测位配置变化的简单方法(必须在每次迭代时进行排序):

                        Index 5 ->
Sorted bit rows:  1  0  0  0  1  1
                  0  0  0  1  1  1
                  0  0  1  1  1  1
                  0  1  1  1  1  1
                  0  1  1  1  1  1

  Index 5 to 4, no change
  Index 4 to 3, change
  Index 2 to 1, change
  Index 1 to 0, change

为了便于检查这些变化,kraskevich建议在我们进行时仅记录每行的最后一个未设置位,这将指示水平序列1的长度和布尔数组({{1数字max)存储遇到的唯一位配置。

1e6

当我们从左向右移动时,记录每行中最后一个未设置位的索引,并记录任何新位配置(最多Numbers: 1, 2, 3 Bits: 1 0 1 0 1 1 ):

1e6

第三次迭代:

Indexes of last unset bit for each row on each iteration
Numbers: 1,  2,  3

A[0]:   -1        arrayHash = [false,true,false,false], count = 1
         0

A[1]:   -1   1    Now sort the column descending, representing (current - index)
         0   0     the lengths of sequences of 1's extending to the left.

As we move from top to bottom on this column, each value change represents a bit
configuration and a possibly distinct count:

  Record present bit configuration b10
    => arrayHash = [false,true,true,false]

  1 => 1 - 1 => sequence length 0, ignore sequence length 0
  0 => 1 - 0 => sequence length 1,
                  unset second bit: b10 => b00 
                  => new bit configuration b00
                  => arrayHash = [true,true,true,false]

(我们继续,因为我们不一定知道arrayHash已经填满了。)

Numbers: 1,  2,  3

A[2]:   -1   1   1
         0   0   0

Record present bit configuration b11
    => arrayHash = [true,true,true,true]