LintCode 838: Subarray Sum Equals K

本文探讨了寻找数组中所有连续子数组,使其和等于特定整数K的问题。通过两种方法解决:一是暴力法,直接计算所有可能的子数组和;二是使用哈希映射优化,记录前缀和的频率,显著提高效率。
  1. 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
Example1

Input: nums = [1,1,1] and k = 2
Output: 2
Explanation:
subarray [0,1] and [1,2]
Example2

Input: nums = [2,1,-1,1,2] and k = 3
Output: 4
Explanation:
subarray [0,1], [1,4], [0,3] and [3,4]

解法1:
我一开始就是用暴力法,但最后会超时。

    int subarraySumEqualsK(vector<int> &nums, int k) {
        int n = nums.size();
        if (n < k) return 0;
        int count = 0;
        vector<int> sums(n);
        sums[0] = nums[0];
        for (int i = 1; i < n; ++i) {
            sums[i] = sums[i - 1] + nums[i];
        }
        for (int i = 1; i < n; ++i) {
            if (sums[i] == k) count++;
            for (int j = 0; j < i; ++j) {
                if (sums[i] - sums[j] == k) count++;
            }    
        } 
        
        return count;
    }

解法2:
参考的网上的解法。感觉很巧妙。
主要思路就是用Hashmap<int, int>来存储Presum和其freq。
如果扫描到某个元素时发现hashmap[presum - k] > 0,说明前面某个presum = 当前presum - k,则把当前的hashmap[当前presum-k]加入到count中。
注意:为什么要设hashmap[0]=1?
看看input: [1,1,1] k = 2
当i=1时,presum = 2,而hashmap[2-2]=hashmap[0],此时count应该加1,所以hashmap[0]=1。
注意后面这个hashmap[0]还可能会变的。
比如说input: [0,0,0,0,0,0,0],hashmap[0]一开始设为1,后面每个i都会逐步累加,一直加到8。

代码如下:

class Solution {
public:
    /**
     * @param nums: a list of integer
     * @param k: an integer
     * @return: return an integer, denote the number of continuous subarrays whose sum equals to k
     */
    int subarraySumEqualsK(vector<int>& nums, int k) {
        int n = nums.size();
        int count = 0, sum = 0;
        unordered_map<int, int> hashmap;  //preSum, freq
        hashmap[0] = 1;
        for (int i = 0; i < n; ++i) {
            sum += nums[i]; 
            count += hashmap[sum - k];   
            hashmap[sum]++;
        }
        return count;
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值