查找最大/最小连续XOR值

时间:2012-12-28 03:01:52

标签: performance algorithm data-structures

我有以下问题:给定一个整数数组(最大大小50000)我必须找到最大的X,

X = a[p] ^ a[p+1] ^ ... ... ^ a[q] for some p,q (p<=q)

此外,我必须找到X的最小值。

我已尝试过这个过程,

sum[i] = a[0] ^ a[1] ^ ... ... ^ a[i] for some i .

我在O(n)和

中预先计算了它

然后某些p,q(p<=q)的X值是,

X = sum[q] ^ sum[p-1]

MaxAns = Max of X for every pair of p,q (p<=q)

MinAns = Min of X for every pair of p,q (p<=q)

但这个过程是O(n ^ 2)。

如果没有O(n ^ 2)算法,我怎么能做到这一点,效率更高?

3 个答案:

答案 0 :(得分:4)

此算法仅适用于位宽有限的无符号整数。

  1. 计算每个数组元素的前缀和(就像在OP中完成的那样)。
  2. 将每个前缀和添加到基数树(对应于根的最高有效位,对应于叶子的最低有效位)。
  3. 在计算sum[q]并将其添加到基数树之间,在部分构建的基数树中搜索 sum[q](以获得最小值X)。要获得X的最大值,请搜索~sum[q]
  4. 如果树中缺少sum[q](或~sum[q])的任何位,切换此位在X的最小值/最大值中并继续向下搜索树
  5. 获取每个前缀的所有最小值/最大值的最小值/最大值
  6. 时间复杂度为O(N log M),其中M是数组元素的最大值。

答案 1 :(得分:1)

这是完全错误的 - 不知道为什么,但是一些测试似乎表明这是错误的。

我认为你可以从“编程珍珠”的第8列获得一些灵感,其中问题基本上是:“给定实数向量x [n],计算在任何连续子向量中找到的最大总和”。

我认为你可以重复使用不同的算法来代替加法和减法 - 或者(在过程中保留大多数有趣的属性:0仍然是中性元素,排他性或者是它自己的逆,交换性)。 / p>

你可以找到幻灯片:http://cs.bell-labs.com/cm/cs/pearls/s08.pdf但我绝对推荐这本书。

答案 2 :(得分:0)

算法:

初​​始化:

ans=a[0]
cur=a[0]

为数组的每个元素循环:

(a) cur = max(a[i], cur^a[i])
(b) ans = max(cur, ans)
return ans

示例: 设数组为1 2 3 5 8 10

ans=cur=1

for i=1:

cur = max(2,3) = 3

ans = max(1,3) = 3


for i=2:

cur = max(3,0) = 3

ans = max(3,3) = 3


for i=3:

cur = max(5,6) = 6

ans = max(6,3) = 6


for i=4:

cur = max(8,14) = 14

ans = max(6,14) = 14


for i=5:

cur = max(10,4) = 10

anx = max(14,10) = 14

所以,ans = 14

这是我在C ++中的实现

int maxXOR(int a[], int n)
{
    int ans = a[0],cur=a[0];
    for(int i=1;i<n;i++)
    {
        cur=std::max(a[i],cur^a[i]);
        ans=std::max(ans,cur);
    }
    return ans;
}

分析:

Time Complexity : O(n)
Space Complexity : O(1)