LeetCode 525-连续数组

给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度。
在这里插入图片描述

题解

涉及到连续子数组的,可以考虑滑动窗口或者前缀和(+哈希表)

题解转载自知春路金刀

方法:前缀和+哈希表

在本方法中,我们可以将数组中的 0 变成 −1,则问题就变成了找到和为0的最长连续子数组,并返回该子数组的最大长度。

思路和算法

本题只需要求出满足要求的子数组的最大长度就行了,并不需要求出具体的子数组。
我们可以使用right指针从左到右扫描一遍数组,将数组中的 0 变成 −1,同时计算当前前缀和prefix[right] (子数组nums[0]…nums[right]之和),然后使用哈希表来存储每个前缀和第一次出现时的末尾元素的下标。

这时我们需要寻找符合条件的子数组,具体思路如下:

通过哈希表找出等于当前前缀和prefix[right]的子数组的下标i。
如果寻找到了这样的子数组,就说明我们寻找到了nums[0]…nums[i]的连续子数组,其之和为prefix[i],其中prefix[i]等于prefix[right],并且i<=right。
我们就可以通过prefix[right] - prefix[i]来得出nums[i+1]…nums[right]子数组之和为0,说明找到了符合新问题2中的条件的子数组。
其子数组的长度为right-i。
另外之所以存储每个前缀和第一次出现的下标是因为我们需要找出满足要求的数组的最大长度,所以下标越小越好。
我们只需要从左到右扫描数组一次,prefix可以实时地去计算,不需要使用数组来保存。
其中哈希表在初始化的时候需要插入{0, -1},目的是为了可以求出符合题中条件的起始元素在下标为0时的连续子数组的情况。

class Solution {
    public int findMaxLength(int[] nums) {
        HashMap<Integer,Integer> map = new HashMap<>();
        int sum=0;
        int ans=0;
        int len = nums.length;
        //为了方便计算从0开始的sum
        map.put(0,-1);
        for(int i=0;i<len;i++){
            if(nums[i]==0){
                sum-=1;
            }else{
                sum+=1;
            }
            //因为是计算最长连续子数组,所以计算该sum值第一次出现的位置
            if(!map.containsKey(sum)){
                map.put(sum,i);
            }else{
                //子数组范围从i到i-map.get(sum)
                ans=Math.max(ans,i-map.get(sum));
            }
        }
        return ans;
    }
}

在这里插入图片描述

你问我答

转载自小虎

  1. 为什么在哈希表中找到了相同的 cur 值则算找到了一串连续数组?
    “如果这是一串连续子数组,那么cur的值,在到达该子数组尾部时(紫色箭头处),与在该子数组前一位时(绿色箭头处),是相等的”
    在这里插入图片描述
  2. 为什么要在哈希表中插入{0, -1}?
    这是为了辅助讨论该连续数组的起始点在 index == 0 的位置的情况,如果最长连续数组在数组的最前方,不插入{0,-1}会得到错误的答案,因此我们一定要插入该辅助键值!具体可以看看动图中的前几位数字看看{0,-1}是如何辅助我们得到答案的!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值