累加和为aim的最长子数组

参考: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];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值