LC525. 连续数组(中等-数学-前缀和 哈希表)

LC525. 连续数组

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

思路:①将0替换为-1  ② 算前缀和  ③ 哈希表遍历  key记录前缀和 value记录其与key相同的所有下标值   并在遍历中一直维护一个maxlength

复杂度: 时间复杂度O(n) 空间复杂度O(n)

 

因为刚刚做完523. 连续的子数组和,所以思路来的很快。可以两个题一起做。下面让我们举一个例子(nums=[0,0,1,0,1])。

① 涉及到连续的子数组和,我们很容易想到用前缀和来做。对于该例子的前缀和是:

   nums:      0  0  1  0  1     

   preSum:  0  0  1  0  2  

   这时候我们发现,这个时候因为0这个特殊的值(多少个0相加都为0)存在,所以导致上述信息对于让0、1个数相等并没有什么帮助。

② 这个时候我们思考,反正是希望0、1二者个数相等,如果将0换为-1,抵消了也没什么关系。换完后如下:

   下标:    -1    0    1   2   3   4            对应的哈希表     

   nums:         -1  -1   1  -1   1                  0     -1                -2

   preSum:0   -1  -2  -1  -2  -1               [-1]    [0  4]      [1   3]

   此时我们观察preSum以及需要满足的条件如下:

           i) preSum[i] == preSum[j]   

           ii)(j-i) %2 ==0

   如 下标为0 和 2 以及 4时候都满足上述条件。如何才能满足问题中另一个限制 最长 呢?

 所以在设计哈希表时候,我们的value设计为一个列表,用来记录第一次出现和最后一次出现相同值的下标。这样最后用里边两个值相减,得到的即为最大长度。得到的哈希表右上所示,最终取4(4-0>3-1).

代码

def findMaxLength(nums):

    preSum, n, hs, maxlength = 0, len(nums), {0: [-1]}, 0

    for i in range(n):
        preSum += 1 if nums[i] else -1  # 将0替换为-1
        index = hs.get(preSum, i)

        if index == i:  # preSum不在hs中
            hs[preSum] = [index]
        elif (i - index[0]) % 2 == 0:
            maxlength = max(maxlength, i - index[0])
            if len(index) > 1:
                hs[preSum].pop()
            hs[preSum].append(i)
    return maxlength

路虽远,行则将至。事虽难,做则必成 

 

   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值