题目:
给定一个二进制数组
nums
, 找到含有相同数量的0
和1
的最长连续子数组,并返回该子数组的长度。
示例 1:
输入: nums = [0,1]
输出: 2说明: [0, 1] 是具有相同数量 0 和 1 的最长连续子数组。
示例 2:
输入: nums = [0,1,0]
输出: 2说明: [0, 1] (或 [1, 0]) 是具有相同数量 0 和 1 的最长连续子数组。
提示:
1 <= nums.length <= 105
nums[i] 不是 0 就是 1
代码 :前缀和
package jianzhioffer;
import java.util.HashMap;
public class offer_11 {
public static void main(String[] args) {
int[] nums = {1, 0, 1, 0};
System.out.println(subarraySum(nums));
}
public static int subarraySum(int[] nums) {
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
int res = 0;
int sum = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i] == 0 ? -1 : 1;
if (map.containsKey(sum)) {
res = Math.max(res, i - map.get(sum));
} else {
map.put(sum, i);
}
}
return res;
}
}
解题思路:
把所有的 0 看成 -1 ,然后求前缀和,只要为 0 ,就说明有相同个数的 0 和 1。
这里比较难以理解的就是为什么map里面要提前put一个(0, -1)。这是因为,如果当前下标 i 的前缀和为 0 ,则是前 i + 1 项和为零。如果当前下标 i 的前缀和为 1 ,则是前 i 项和为 0 ,所以,为了统一运算,要提前put一个 (0, -1)。
(1)创建一个HashMap集合,用来存放前缀和,键为和,值为下标
(2)因为要求最长的数组长度,所以键为 0 和 1 的情况只需要分别存入依次即可,下次遇到前缀和相同时,更新最长数组长度即可。
参考链接: