从数组中找到具有max XOR的子数组(使用trie)

时间:2016-08-29 19:08:25

标签: arrays algorithm tree bit-manipulation trie

问题陈述是:

  

给定一个整数数组,找到具有最大异或的子数组。

一些例子是:

Input: arr[] = {1, 2, 3, 4}
Output: 7
The subarray {3, 4} has maximum XOR value

Input: arr[] = {8, 1, 2, 12, 7, 6}
Output: 15
The subarray {1, 2, 12} has maximum XOR value

我发现quora post提供了对问题解决方案的解释,但我不能完全理解正在解释的内容。

该帖子首先引入了与上述问题类似的问题(帖子中的问题1):

  

给定一个整数数组,我们必须找到两个XOR最大的元素

然后描述了一个可以处理两种类型查询的trie数据结构:

  
      
  1. 插入数字X
  2.   
  3. 给定Y,找到Y的最大XOR,其中包含到目前为止已插入的所有数字。   如果我们有这个数据结构,我们将继续插入整数,并使用第二类型的查询,我们将找到最大的XOR
  4.   

enter image description here 上面的图像处理查询类型1.对于查询类型2,帖子具有以下内容:

  

假设我们的数字Y是b1,b2 ... bn,其中b1,b2 ..是二进制位。我们从b1开始。现在为了使XOR达到最大值,我们将在采用XOR后尝试将最重要的位1设为最大值。所以,如果b1为0,我们需要1,反之亦然。在trie中,我们转到所需的位侧。如果没有有利的选择,我们会走另一边。在i = 1到n的情况下全部执行此操作,我们将获得最大的XOR。

这里有一些混乱点。一个是:如何使用trie来找到最大XOR直到阵列中当前点的两个元素?他们似乎在说这样的话:

例如 array = {1,2,3,4},当前数字为3 - > 0011(4位表示)意味着1和2已经插入到trie中。到目前为止,max xor应该是数字1和2(产生3)。使用帖子中提供的方法,似乎max xor可以存储在一个变量中,这样当数组中的最后一个数字与trie的当前stat进行xored时(我假设它有元素) 1,2和3已插入),变量到目前为止将具有最大值。 但是算法如何存储哪两个元素已经xor才能产生最大值?

最后,这种方法的逻辑应该适用于问题(帖子中的问题2):

  

给定一个整数数组,找到最大XOR

的子数组

这里提供了以下解决方案:

  

假设F(L,R)是从L到R的子阵的XOR。   这里我们使用F(L,R)= F(1,R)XOR F(1,L-1)的性质。怎么样?   假设我们的最大XOR的子阵列在位置i处结束。现在,我们需要最大化F(L,i)即。 F(1,i)XOR F(1,L-1)其中L <= i。假设我们在所有L&lt; = i中插入F(1,L-1),那么它只是问题1。

我真的不明白F(L,R)= F(1,R)XOR F(1,L-1)的性质。我在这里假设R是最大子阵列的右边界,而L是它的左边界,但是不清楚为什么F(1,i)需要与F(1,L)进行异或-1)。从这一点来看,问题1的逻辑如何适用于此?

我意识到这个问题很长,但问题是多方面的,似乎有必要包括问题的这些基本部分。

2 个答案:

答案 0 :(得分:3)

第一个问题:当您向trie添加元素时,可以在叶子中存储指示数组中元素索引的附加信息。当您遍历trie并使用Y(如您的问题中所述)到达最大化xor的叶子时,您可以记录两个索引以及最大值(Y的索引称为其你要添加的元素)。

平等f(l, r) = f(0, r) ^ f(0, l - 1)已被证明here

一旦我们得到了这个相同的解决方案并解决了第一个问题(上面描述了稍微修改以记录索引),我们立即得到第二个问题的解决方案。怎么样?我们可以为所有有效f(i)计算i,然后运行此算法以获得最大化xor的两个索引。让他们为LR,其中L < R。然后答案是[L + 1, R]子阵列。

答案 1 :(得分:0)

从克拉斯科维克的答案中可以理解数学上的相等性。

此后,我们需要使用包含前缀xor值,指向left(0)和right(1)子代的指针的结构,将所有前缀xor(pre_xor)存储在Trie中。

此Trie的所有叶子节点值将包含前缀xor,所有非叶子节点的值将为0。

首先用0初始化pre_xor,然后将0插入特里。

然后,在接受输入后,将其与pre_xor进行异或,以得到异或直到插入最后一个元素,然后将此pre_xor插入特里。

当我们将前缀xor(pre_xor)插入第ith个元素(充当等式的R,即f(0,r))时,我们遍历trie来查找XOR为最大的合适的l也就是说,如果pre_xor的最右边数字包含1,那么如果存在,我们将向0侧移动(因为0 ^ 1 = 1)。

到达叶节点后,我们找到了使Xor最大化的最合适的l,该值就是给定方程式中所讨论的f(0,l-1)。

由于这个f(0,l-1)的xor和f(0,r)的xor = f(l,r)(在给定相等的情况下),所以我们使f(0)的xor最大化, l-1)和f(0,r),我们找到了子数组的最大xor(直到第ith个元素)。