给定一个只包含0或1的数组,找出其中包含相同0的个数和1的个数的最
长子序列,输出子序列的长度, 要求在O(n)的时间复杂度内完成。
如:对于数组[0,0,1,1,0],输出结果为4。子序列[0,0,1,1] 或
[0,1,1,0] 为符合条件的最长子序列,包含了两个1和两个0,个数相同。
来自基础:
给定一个值可能是正、负和0的数组,以及一个累加和target,返回这个数
组中累加和为target的最长子数组的长度。

 

思路:

利用一个map  key :某个累加和sum    value :这个累加和最早出现的位置

map.put(0, -1); // 非常重要 意思是累加和为0 最早出现的位置为 -1 默认

sum:表示从0到此位置的累加和   即从当前位置找(sum-target)最早出现的位置 index   则当前位置减去index就为当前位置能够

          找到累加和为target的最大长度

public static int maxLength(int[] arr, int aim) {

		if (arr == null || arr.length == 0) {
			return 0;
		}
		// key 某个累加和sum value 这个累加和最早出现的位置
		// 取以每个位置为结尾的等于定值的子数组的最大长度的最大值
		HashMap<Integer, Integer> map = new HashMap<>();
		map.put(0, -1); // 非常重要 意思是累加和为0 最早出现的位置为 -1 默认
		int res = 0;
		int sum = 0; // 前缀和 到i位置
		for (int i = 0; i < arr.length; i++) {
			sum += arr[i]; // arr[0..i]的和 到当前位置的累加和
			if (map.containsKey(sum - aim)) { // 能找到sum-aim出现的最早位置
				// i-map.get(sum-aim):用当前位置(和为sum)-sum-aim出现的最早位置 则剩下的和为aim
				res = Math.max(i - map.get(sum - aim), res); // 更新最大长度 i-(map.get(sum-aim)+1)+1
			}
			if (!map.containsKey(sum)) {// 只放和为sum出现的最早位置
				map.put(sum, i);
			}
		}

		return res;

	}