[算法--前缀和] 连续数组

接下来, 我们继续分享一道题目 -> 连续数组

  很显然, 这个题目要求我们找一个最长的子数组, 然后该子数组1和0的个数是一样的.
  我们可能直接想到的就是暴力求解, 依次枚举子数组, 然后看该子数组是否满足条件, 返回其中length最大的子数组. 显然我相信这个方法大家都会, 就不过多赘述了. 那对于这个题目我们该如何去解决呢?

1. 不好做, 要学会转化问题.

转换就是一个很好的思路.
  实际上, 这个题目含义我们还可以转化为求一个子数组, 该子数组之和等于该子数组的长度的一半.
  不过这样转化的化还是不太明晰, 我们可以干脆直接把这个数组的0换成-1, 这样题目也就变成了: 求一个子数组, 该子数组之和为0(因为要求1和-1的个数一样).

2. 无论是双指针还是前缀和, 本质上大概率是对暴力求解的优化.

  实际上, 我们明明有暴力求解的思路却不用这种方法, 原因就在于暴力求解时间复杂度高, 所以说我们的一些算法(前缀和, 双指针)就是利用一些思路来对暴力求解进行优化的.

3. 这道题不能用双指针(滑动窗口)优化, 因为该数组并非呈递增性质.

  我们双指针优化暴力求解的本质在于我们可以以数组的递增/递减性, 来根据趋势避免不必要的计算, 而现在这个数组是不确定性的, 比如我们假如说现在0和1的个数不匹配, 你此时选择如何移动指针呢? 只有当具有单调性的一个数组我们才可以进行确定.

4. 解法是: 前缀和 + 哈希表.

最终我们经过考虑, 认为前缀和才有可能会提高暴力求解算法的一个效率. 前面我们把0变成-1, 因为这样可以很好求我们要找的子区间.

那我们下面来进行一步一步进行优化:
  首先, 我们可以把所有穷举的子数组都列举出来, 我们可以给他们分个类, 比如都以i位置为结尾的为一组. 我们下面来展现其中的一组来代表所有组的情况:
在这里插入图片描述
我们假设i为数组中的任意位置, 用sum[i]来表示[0,1]区间所有元素的和.
  想要知道最大的以i位置为结尾的和为0的子数组, 就要找到一个从左向右的第一个x是的[x1,i]区间内的所有元素和为0, 那么[0,x1-1]区间内的和就是sum[i]了, 于是问题就变成了: 在[0, i-1]这个区间内, 找到dp数组中值为sum[i]的元素.
在这里插入图片描述

5. 为什么不是直接找这个区间内哪个子数组之和为0?

  还记得我们的目的吗? 我们是为了利用前缀和来减少时间复杂度的, 而如果直接在这个区间内找哪个子数组和为0, 那么时间复杂度就最少是O(N*N)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值