[LeetCode] 560. 和为K的子数组(和值数组,哈希)

560. 和为K的子数组

给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。
在这里插入图片描述
解题思路: 本题一开始以为是用滑动窗口解题,但是在写代码的时候发现,整数数组的值有正有负,和值也不是单调的,因此窗口的收缩方向不好判断,于是换了种思路。此题的背景是求和,而且是求序列的连续子集和,那么为了降低时间复杂度,往往我们会将0到当前索引位置的和值求出来放在一个和值数组中,然后求某段子数组的和值,比如[i,j],只需计算SUM[i,j]=sum[j]-sum[i]+num[i],但是算法的时间复杂度为 O ( N 2 ) O(N^2) O(N2),好像至此,OJ也能通过这个解法。然后看了grandyang的解法,再结合本题给出的标签,哈希,题目认为的最优解法是哈希解法。

哈希解题思路:我们可以分析下面这个图,这段序列取自给定数组nums,左边界是nums的左边界,右边界是nums中间某个点,我们分析这个当前状态,我们的和值k是有中间某段连续序列组成,因此我们依然在遍历的过程中将当前位置到0-index点的和值求出来,但是我们不用保存在一个数组,仅仅维护一个到当前位置的和值sum即可,在遍历的过程中,我们将这个和值与它出现的个数用哈希映射起来,那么当我们遍历到图中这个状态时,我们要判断和值k是否存在,只需判断和值sum-k是否存在,顺着这个思路,此题可解。

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

总结

对连续求和值的题做一个简单的总结和回顾。连续和值的解法一般用和值数组即可降低一个维度的时间复杂度,这是通常解法,若涉及到判断和值个数的问题,比如这题,那么需要想到用哈希来记录值和个数的映射,这个直接想比较难想到,但是另一个想法我们是很常见的,即,当我们需要判断或者找寻的和值为k时,若已知我们当前位置到某个位置(常规是起点0-index)的和值,那我们只需要判断或者找寻从起点位置到某个位置的和值为sum-k的序列,就可以解决和值为k的问题了。

参考资料

https://www.cnblogs.com/grandyang/p/6810361.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值