最大子序列和的问题经常被问到,这个问题有很多解法,比如这里:最大子序列和整理,复杂度从O(n^3)到O(n)。
最大子序列异或的运算用到了异或运算的性质,以及Trie树。大体思路为,ai xor …xor aj = (a0 xor …xor ai-1) xor (a0 xor … xor aj)。
看代码的,懒得写了,不懂再交流。
public class Solution {
BitNode root = new BitNode();
//int类型的位数为32位,这里表示要移动的最大位数
int bitNum = 32-1;
int maxValue = Integer.MIN_VALUE;
int leftIndex = -1;
int rightIndex = -1;
//插入一个xor值,先存高位,再存低位
public void insert(int index,int xor){
BitNode temp = root;
//从高位开始构造一个Trie树
for(int i=bitNum;i>=0;i--){
int bit = (xor>>i)&(0x1);
if(temp.bits[bit]==null){
temp.bits[bit] = new BitNode();
}
temp = temp.bits[bit];
}
//到这里时,temp为最后一个叶子节点
temp.index = index;
temp.xorValue = xor;
}
//搜索在index下标下,与当前连续xor异或最大的值,若此值大于当前最大值
//则更新最大值与下标
public void search(int index, int xor){
BitNode temp = root;
for(int i=bitNum;i>=0;i--){
int bit = (xor>>i)&(0x1);
if(temp.bits[1-bit]!=null){
temp = temp.bits[1-bit];
}else{
temp = temp.bits[bit];
}
}
int curXor = temp.xorValue ^ xor;
if(curXor>maxValue){
maxValue = curXor;
leftIndex = temp.index+1;
rightIndex = index;
}
}
//求一个数组的连续子数组的最大子序列xor值,运用异或运算的性质 xor,
public int maxSequentialXor(int[] array){
if(array==null || array.length==0){
return -1;
}else if(array.length==1){return array[0];}
int len = array.length;
int[] xorArray = new int[len];
xorArray[0] = array[0];
for(int i=1;i<len;i++){
xorArray[i] = xorArray[i-1]^array[i];
}
insert(-1,0);
for(int i=0;i<len;i++){
search(i,xorArray[i]);
insert(i,xorArray[i]);
}
System.out.println(maxValue);
System.out.println(leftIndex);
System.out.println(rightIndex);
return 0;
}
public static void main(String[] args) {
Solution s = new Solution();
int[] a = {1,34,7, 2, 10};
s.maxSequentialXor(a);
}
}
//TrieNode
class BitNode {
BitNode[] bits = new BitNode[2]; //每一个节点有26个孩子,每个孩子安装字典顺序进行排列,'a'排在第一个,'b'排在第二个,...,'z'排在最后一个
int index; //表示这一点存的连续xor值的下标
int xorValue; //连续xor值
}