题目地址:
https://www.lintcode.com/problem/722
给定一个长 n n n数组 A A A,求最大的子数组异或和。
思路是Trie。考虑 A A A的前缀异或和数组 p p p,那么考虑 p [ i ] p[i] p[i]的时候,要求出 max j < i p [ i ] ∧ p [ j ] \max_{j<i} p[i]\wedge p[j] maxj<ip[i]∧p[j],这可以将每个数看成 32 32 32位二进制整数,然后将其存入Trie,每次从树根走的时候尽量走与当前二进制位不同的那条路。那么显然答案就是 max i ≥ 1 max j < i p [ i ] ∧ p [ j ] \max_{i\ge 1} \max_{j<i} p[i]\wedge p[j] maxi≥1maxj<ip[i]∧p[j]。代码如下:
public class Solution {
class Node {
Node[] next;
public Node() {
next = new Node[2];
}
}
Node root;
int insert(int x) {
int res = 0;
Node cur = root, node = root;
for (int i = 0; i < 32; i++) {
int bit = x >> 31 - i & 1;
// node用来将x插入进去
if (node.next[bit] == null) {
node.next[bit] = new Node();
}
node = node.next[bit];
// cur用来看与x最大异或能得到什么数
if (cur.next[bit ^ 1] != null) {
cur = cur.next[bit ^ 1];
res += 1 << 31 - i;
} else {
cur = cur.next[bit];
}
}
return res;
}
/**
* @param nums: the array
* @return: the max xor sum of the subarray in a given array
*/
public int maxXorSubarray(int[] nums) {
// write code here
root = new Node();
int pre = 0, res = 0;
insert(0);
for (int x : nums) {
pre ^= x;
res = Math.max(res, insert(pre));
}
return res;
}
}
时空复杂度 O ( n ) O(n) O(n)。