给定一个只包含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;
}