LeetCode560题:折腾了好长时间的一道题:和为K的子数组

在这里插入图片描述这题是一道经典的前缀和,前缀和其实就是数列里面的前N项和;要找K=2的连续子数组,可以是nums[0]+nums[1],也可以是nums[2]+nums[3],但是nums[2]+nums[3]可以写成nums[1]+nums[2]+nums[3]-nums[1],即前两项和(从0开始计数)-前0项和;这道题的思路就是计算前N项和存入一个表中,定义:unordered_map<int,int> map1,存前n项和以及前n项和出现的次数(因为可能有负数导致前i,j项和相等)这样我们每次查找一个前n项和-k,如果在表中能找到,找到几个就说明有几个结果;
下面直接上代码:

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
       unordered_map<int,int> map1;
       map1[0]=1;
       int sum=0;
       int res=0;
       for(int i=0;i<nums.size();i++)
       {
           sum+=nums[i];
           if(map1.find(sum-k)!=map1.end())
           {
               res+=map1[sum-k];
           }
           map1[sum]++;
       }
        return res;
    }
};

答案如上:
下面我们来思考一个问题:
在这里插入图片描述
第15行代码能否放在第11行呢?
既然我来写这个博客了,那答案明显就是不能,原因呢?
我们假设k=0;要求一个连续的子数组,使其和为0;
在k=0的情况下,我们本应该找的是sum-k;但是如果k=0;这样要找的对象就变成了sum,实际上是啥都没有,是一个空序列,我们如果将map放在第11行的位置,每次都能找一个sum,答案就变的非常离谱;
那这个问题的深层原因呢?
我说一点我的理解:
不知道你们觉不觉得这个问题很像双指针呢;sum相当于右指针,sum-k相当于左指针,如果将map放在11行相当于俩指针重合了;我们在做前缀和的时候,要求一个presum[j]-presum[i]=k;需要 i 严格<j;才能保证俩指针之间有数,如果相等,每次的差都等于0;每次都符合k=0;
另外呢,简单理解一句话;sum是前i+1项和,map要保存前i项和;如果放在上面就是前i+1项;在K=0的时候会出错;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值