LeetCode560. Subarray Sum Equals K(和为K的子数组)

560. Subarray Sum Equals K

Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.

Example 1:

Input:nums = [1,1,1], k = 2
Output: 2

Note:

  1. The length of the array is in range [1, 20,000].

  2. The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].


题目:给定一个数组,计算和为K的子数组的个数(子数组要求是连续的)。

思路1:首先第一想法就是暴力循环?。第一层循环变量是子串在数组中的起始位置,第二层循环变量是子串的长度,然后将子串的和和目标值K相比较。

工程代码下载

#include <iostream>
#include<vector>
#include<unordered_map>
using namespace std;


//Using Cummulative sum
class Solution1 {
public:
    int subarraySum(vector<int>& nums, int k) {
        if (nums.size() == 0)
            return 0;

        int res = 0;
        vector<int> sum(nums.size() + 1);
        sum[0] = 0;
        for (int i = 0; i < nums.size(); i++)
            sum[i + 1] = sum[i] + nums[i];

        for (int i = 0; i < nums.size(); i++)
            for (int j = i + 1; j <= nums.size(); j++)
                if (sum[j] - sum[i] == k)
                    res++;

        return res;
    }
};


int main()
{
    Solution1 sln;
    vector<int> testcase{ 1,1,1 };
    cout << sln.subarraySum(testcase, 2) << endl;
    std::cout << "Hello World!\n";
}

思路2:另一种方式是通过map来记录前n个元素中已经出现过的和(和的计算均从最左侧的元素开始),以及对应的次数。用cur_sum来表示前j个元素的和,前j-1个元素出现过的和的哈希表集合记为sum_counts,那么如果我们要确定前j个元素中是否有子串的和为目标值K

只需要判断哈希表sum_counts中是否有cur_sum-K这个键值,

怎么理解呢,因为sum_counts中存放的是sum(0,i),即元素0到元素i的总和,而cur_sum的值等于sum(0,j),如果子串(i到j)的和为K,我们可以得到sum(0,i) + K = cur_sum,变换一下表达式可以得到sum(0,i) = cur_sum-K,如果sum(0,i)的值在sum_counts中存在,那么从第i个位置开始到j的元素和就为目标值K了。

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        // key:表示前n个元素的和sum;value:表示这个和出现过的次数
        unordered_map<int, int> mp;
        int cur = 0;  // cur表示的是前n个元素的和
        int res = 0;
        mp[0] = 1;  // 注意:和为0的次数要初始化为1次
        for(auto num : nums){
            cur += num;
            int target = cur - k;
            auto iter = mp.find(target);
            if(iter != mp.end()){
                res += iter->second;
            }
            mp[cur]++;
        }
        return res;
    }
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值