参考:https://www.cnblogs.com/zzw1024/p/11070215.html
扩展1
一个数组中要么是奇数,要么是偶数,求奇数和偶数相等的最长子数组。
思路
用1表示奇数,用-1表示偶数,那么就是求累加和为0的最长子数组,参考上面
扩展2
求一个数组怎样划分可以使得子数组异或为0的个数最多。
思路
动态规划:
定义一个dp数组,dp[ i ]表示以 i 结尾可以划分的最多个数
对于第i个数的怎么求出呢:
1.当i-1最后子数异或和不为0时,dp[i] = dp[i-1]
2.当i-1为最后异或和时,dp[i] = dp[k-1]+1, K为上次距离i-1最近的一组异或和的
异或和用map来存储,遍历到一个数,异或它,求异或后的数在map中最近的索引位置,因为0异或这个数还是这个数。
public int mostEOR(int[] arr){
if(arr == null || arr.length == 0){
return 0;
}
int eor = 0;
int[] dp = new int[arr.length];
Map<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
dp[0] = arr[0] == 0 ? 1 : 0;
map.put(dp[0], 0);
for(int i = 1; i < arr.length; i++){
eor ^= arr[i];
if(map.containsKey(eor)){
int eorIndexPre = map.get(eor);
dp[i] = eorIndexPre == -1 ? 1 : dp[eorIndexPre] + 1;
}
dp[i] = Math.max(dp[i], dp[i-1]);
map.put(dp[i], i);
}
return dp[dp.length-1];
}