Leetcode525.连续数组(又是连续之类的题目,结合前缀和)

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

示例 1:

输入: nums = [0,1]
输出: 2
说明: [0, 1] 是具有相同数量01的最长连续子数组。

示例 2:

输入: nums = [0,1,0]
输出: 2
说明: [0, 1] ([1, 0]) 是具有相同数量01的最长连续子数组。

思路:
   第一个想法就是暴力法搜索,计算数组中所有子集和, 然后记录子集和的下标,一旦子集的长度是子集和两倍,而且子集和大于0,避免00的情况。我们就返回长度,最终比较出最大长度。注意到我们的子集和从尾巴开始往前面累加。这样只需要2重循环。时间复杂度最大0(n^3),但是还是超时了。

class Solution {
public:
    int findMaxLength(vector<int>& nums) {
    int len=nums.size();
    if(len<2)
    return 0;
    int maxlength=0;
    //暴力法
    
    for(int i=len-1; i>=1;i--){
        int sum=nums[i];
        for(int j=i-1;j>=0;j--){
            sum+=nums[j];
            if(2*sum==(i-j+1) && sum>0)
              maxlength=max(maxlength,i-j+1);
        }
    }
    return maxlength;
    }
};

解决办法:前缀和+哈希表,和之前前缀和的题目很像,只是我们更换了下筛选条件。我们知道01数量一致,我们把数组中0变成负1,那么0 1数量一致的子集就变成和为0的子集。即,我们不断存入这个前缀和到哈希表,如果出现过这个和的值,什么意思,意味着中间某一段到当前sum和为0,那就返回之前存的坐标和当前坐标的差,就是长度! 注意到我们要求最大长度,所以同样的sum我们只记录一次,程序中就是如果没出现这个值就进入哈希表,出现过就计算长度就好了。这样出来的就是最大长度。然后考虑一个情况,就是当前值就是0 1相同,sum=0怎么办,一开始没进入这个,所以我们要提前设置map[0]=-1,我们下标从0开始,0–1=1,以此类推没毛病。而且其他的中间过程 3-1=2也是对的。

class Solution {
public:
    int findMaxLength(vector<int>& nums) {
    int len=nums.size();
    if(len<2)
    return 0;
    //这个题目有点像昨天的题目啊,如果自己0=-1,累加值=0,那sum1=sum2了
    unordered_map<int,int>map;
    int sum=0;
    int maxlength=0;
    map[0]=-1;
    for(int i=0;i<len;i++){
      //变成0变成-1;
      if(nums[i]==0){
        int ans=-1;
        sum=sum+ans;
      }
      else{
       sum=sum+nums[i];
      }
      if(map.count(sum))
        maxlength=max(maxlength,i-map[sum]);
      else
        map[sum]=i;
    }
    return maxlength;       
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值