题目描述
给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的 最长连续子数组,并返回该子数组的长度。
力扣:525. 连续数组
输入 :nums = [ 0 , 1 , 1 , 0 , 1 , 1 , 1 , 0]
输出 :4
说明 :[0 , 1 , 1 , 0] 具有相同数量 0 和 1 的最长连续子数组
题目分析
如何控制相同数量的 0
和 1
呢?可以借助前缀和的思想。我们可以把原输入数组中的 0
全部换成 -1
,构成新数组 newArray
,观察 newArray
的前缀和。
通过观察:i_1
和 j_1
两个位置的前缀和都是 1
,原数组 [i_1 + 1 , j_1]
恰好有相同数量的 0
和 1
。
又比如 i_2
和 j_2
两个位置的前缀和都是 0
,原数组 [i_2 + 1, j_2]
也有相同数量的 0
和 1
。
所以,只要用 HashMap 记录第一次出现过的前缀和的索引 ,遇到相等的前缀和就用当前的索引减去第一次出现该前缀和的索引,获得最长的长度 。
class Solution {
public int findMaxLength(int[] nums) {
Map<Integer , Integer> map = new HashMap<>();
map.put(0 , -1);
int sum = 0 , maxLen = 0;
for(int i = 0 ; i < nums.length ; i ++){
sum += nums[i] == 1 ? 1 : -1;
// 如果不是第一次出现 , 用当前索引 - 第一次出现该前缀和的索引
if(map.containsKey(sum)){
maxLen = Math.max(maxLen , i - map.get(sum));
}
else map.put(sum , i); // 保存第一次出现该 前缀和 以及 索引
}
return maxLen;
}
}