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
Constraints:
The length of the array is in range [1, 20,000].
The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].
首先我们非常容易想到的暴力破解方法:
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int element = nums.size();
int cnt = 0;
for(int start = 0;start < element;start++)
{
int sum = 0;
for(int i = start ;i < element;i++)
{
sum += nums[i];
if(sum == k)
{
cnt++;
}
}
}
return cnt;
}
};
复杂度n的平方,性能也如预料中一样,非常的差,差到我们只比5.01%的人快。
Runtime: 1268 ms, faster than 5.01% of C++ online submissions for Subarray Sum Equals K.
Memory Usage: 16.2 MB, less than 98.62% of C++ online submissions for Subarray Sum Equals K.
另外一种高效,但相对难想到的方法:
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
std::unordered_map<int, int> seen = {{0, 1}};
int count = 0, sum = 0;
for (auto n: nums) {
sum += n;
count += seen[sum - k];
seen[sum]++;
}
return count;
}
};
性能相对方法一提升10倍,运行时间90ms左右.思路也非常奇妙,我们一直计算累加和,如果当前和减去k在前面已经求出来的累加和中,那么从那个元素之后到当前元素之间的和即为k,打完收工,睡觉大吉。