011、0和1数量相同的子数组

剑指 Offer II 011. 0 和 1 个数相同的子数组

题目

给定一个二进制数组 nums , 找到含有相同数量的 01 的最长连续子数组,并返回该子数组的长度。

示例 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

 

思路

前缀和+哈希表解题

1、首先题目要求找到0和1数量相等的最长子数组,我们可以把0看做-1,这样就变成了找到一个最长的子数组使得数组里面的元素和为0。我们把nums=[0,1,0,1,1]看做nums=[-1,1,-1,1,1]。(下面以这个为例)

2、依次求得前n个整数的和sum

nsum
0 0
1 -1
2 0
3 -1
4 0
5 1

根据这个表我们可以发现规律:当sum值相等时,我们用其对应的n值相减,得到的就是一个数组内各元素和为0的数组

例如n=1和n=3的sum都是-1,

所以我们用 [-1,1,-1,1,1] - [-1,1,-1,1,1] = [-1,1,-1,1,1]

image-20220312123618749

得到的这个sum为0的子数组就是一个符合题目要求的子数组

3、建立一个哈希表来存放这些前缀和

Map<Integer, Integer> map = new HashMap<>();
map.put(0, 0);//先把前0和数的前缀和放进哈希表
keyvalue
0 0

遍历数组

int sum=0;
int ans=0;
```
for(int i = 0; i < nums.length; i++)
sum += nums[i] == 0 ? -1 : 1;

如果哈希表中不存在key值为sum,map.put(sum, i + 1);

keyvalue
0 0
-1 1

如果哈希表中存在key为sum,

ans = Math.max(ans, i+1-map.get(sum));

因为我们要求的是最大的子数组的长度,所以key值相同的情况下我们只需保留小的value

 

代码

public int findMaxLength(int[] nums) {
  int ans=0;//返回值
  int sum=0;//和
  Map<Integer, Integer> map = new HashMap<>();
  map.put(0, 0);//前0个整数sum为0
  for (int i = 0; i < nums.length; i++) {
      sum += nums[i] == 0 ? -1 : 1;//把0当成-1
      //哈希表中是否存在key值为sum
      if (map.containsKey(sum)) {
          ans = Math.max(ans, i+1-map.get(sum));
      } else {
          map.put(sum, i + 1);
      }
  }
  return ans;
}
posted @ 2022-03-12 13:03  彬不冰  阅读(158)  评论(0)    收藏  举报