我有以下问题:给定一个整数数组(最大大小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)算法,我怎么能做到这一点,效率更高?
答案 0 :(得分:4)
此算法仅适用于位宽有限的无符号整数。
sum[q]
并将其添加到基数树之间,在部分构建的基数树中搜索 sum[q]
(以获得最小值X)。要获得X的最大值,请搜索~sum[q]
。sum[q]
(或~sum[q]
)的任何位,切换此位在X的最小值/最大值中并继续向下搜索树时间复杂度为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)