当前位置: 代码迷 >> 综合 >> 146.(560)和为K的子数组
  详细解决方案

146.(560)和为K的子数组

热度:25   发布时间:2024-02-05 13:22:49.0

题目描述:

给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。

示例 1 :

输入:nums = [1,1,1], k = 2
输出: 2 , [1,1] 与 [1,1] 为两种不同的情况。
说明 :

数组的长度为 [1, 20,000]。
数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。

思路:

前缀法:

1、假设存在区间 [start,end]内的元素和为k,说明从0到end的和,从0到start-1的和,两者的差为k

2、扫描数组,计算从0到当前 i 位置的和sum,同时计算sum-k是否存在,如果存在,说明上面的1成立,存在以当前 i 位置为结尾的子序列,同时,将sum-k的标记加一;不存在,就将该sum标记为出现一次。

3、初始m[0]=1,是因为sum-k为零的情况,即start为初始位置

代码:

暴力法:

class Solution {
public:int subarraySum(vector<int>& nums, int k) {int len = nums.size(),res=0,sum=0;for(int i=0;i<len;i++){sum=0;for(int j=i;j<len;j++){sum+=nums[j];if(sum==k) res++; }}return res;}
};

优化:前缀法

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

执行效率:

暴力法:

执行用时:1632 ms, 在所有 C++ 提交中击败了20.29%的用户

内存消耗:16.2 MB, 在所有 C++ 提交中击败了91.05%的用户

前缀法:

执行用时:92 ms, 在所有 C++ 提交中击败了79.01%的用户

内存消耗:22.3 MB, 在所有 C++ 提交中击败了53.16%的用户

  相关解决方案