数据结构 -- 数组累加和

解题思路:必须以某个位置结尾的情况下,答案一定在其中。

1. 给定一个数组,有正有负,求累加和为target的最长子数组
解析:计算前缀和数组,

  • sum表示从开始到 i 位置的累加和。
  • Map:key指累加和,value指最早出现的位置。
public int maxLength(int[] arr, int k){
	if(arr == null || arr.length == 0) return 0;
	Map<Integer, Integer> map = new HashMap<>();
	map.put(0, -1);
	int ret = 0; int sum = 0;
	
	for(int i = 0; i < arr.length; i++){
		sum += arr[i];
		
		if(map.containsKey(sum - k))
			ret = Math.max(ret, i - map.get(sum - k));
			
		if(!map.containsKey(sum))
			map.put(sum, i);
	}
	return ret;
} 

2. 一个数组中,有奇数和偶数,求奇偶个数相同的最长子数组
解析:把奇数置为1, 偶数置为-1, 求累加和为0的最长数组

3. 一个数组中,含有0 1 2,求含有1和2数量相同的子数组有多少
解析:把2置为-1,求累加和为0的子数组

4. 给定一个数组,可任意把数组切分成不相容的子数组,使异或和为0的子数组最多,求最多的个数
解析:先求0~i 范围,再求 0 ~ i + 1范围
假设0 ~ i 数组存在最优化分,两个可能:

  • i 所在子数组异或和不为0,则0 ~ i 和 0 ~ i - 1 最多划分的个数相同
  • i 所在子数组异或和为0,则存在k一定是距离 i 最近的异或和为0的位置(若 0 ~ i 异或和为sum,则找出从 0 ~ i 之间为sum 的最晚的位置,即为pre)
    dp[i] = math.max(dp[i - 1], dp[pre] + 1)
public int mostEOR(int[] arr){
	int ans = 0;
	int xor = 0;
	int[] dp = new int[arr.length];
	Map<Integer, Integer> map = new HashMap<>();
	map.put(0, -1);
	
	for(int i = 0; i < arr.length; i++){
		xor ^= arr[i];
		if(map.containsKey(xor)){
			int pre = map.get(xor);
			dp[i] = pre == -1 ? 1 : dp[pre] + 1;
		}
		
		if(i  > 0)
			dp[i] = Math.max(dp[i - 1], dp[i]);
			
		map.put(xor, i);
		ans = Math.max(ans, dp[i]);
	}
	return ans;
}

5. 给定一个数组,求子数组的最大异或和
:若 E1^E2=E3 --> E1^E3=E2 ,E2^E3=E1
即:( 0到 i 的异或和)^(0到 j - 1 的异或和) == j 到 i 的异或和
解法 : 使用动态规划:dp记录 0 ~ i 的异或值

public int getMax(int[] arr){
	int max = Integer.MIN_VALUE;
	int eor = 0;
	int[] dp  = new int[arr.length];

	for(int i = 0; i < arr.length; i++){
		eor ^= arr[i];
		max = Math.max(max, eor);
		for(int j = 0; j < i; j++){
			int curEor = eor ^ dp[j];
			max = Math.max(max, curEor);
		}
		dp[i] = eor;
	}
	return max;
}
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值