Description
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].
Solution 1(C++)
static int x=[](){std::ios::sync_with_stdio(false); cin.tie(NULL); return 0;}();
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int res=0, len=nums.size();
vector<int> presum(1,0);
for(int i=0; i<len; i++){
for(int j=0; j<presum.size(); j++){
presum[j] += nums[i];
if(presum[j] == k) res++;
}
presum.push_back(0);
}
return res;
}
};
Solution 2(C++)
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int s = 0;
unordered_map<int, int> m;
m[0]++;
int ans = 0;
for (int v: nums)
{
s += v;
auto it = m.find(s-k);
if (it != m.end())
ans += it->second;
m[s]++;
}
return ans;
}
};
后续更新
可以参考:
- LeetCode-713. Subarray Product Less Than K。
- LeetCode-795. Number of Subarrays with Bounded Maximum
- LeetCode-209. Minimum Size Subarray Sum
算法分析
解法一是自己做的,emmmm,居然在已提交的答案中找不到比我还慢的···,这应该是我做的最慢的一道题了。参考解法二,其实两者的核心思想差别不大,而且解法二用了更好的数据结构,那就是map。
这道题也是找连续子数组的和,反正就是连续子数组,解法一的思想其实是借鉴了之前做的一道题,一个新的元素加入,会对之前元素组成的子数组的数量有怎样的影响;
可参考:LeetCode-795. Number of Subarrays with Bounded Maximum。
解法二其实利用了一个数学公式:
a(i)+a(i+1)+...+a(j)=[a(0)+a(1)+...+a(j)]-[a(0)+a(1)+...+(i)]
=S(j)-S(i)
所以,解法二中map储存的都是S(i),然后去查找S(i)-k在map中的值。
这种思想,我记得我曾经在树中的一道题做过,找到了
可参考:LeetCode-437. Path Sum III。
所以啊,这种“中间”连续路径的问题,可以将中间连续路径转换为起点到两个终点的路径之差的问题。
程序分析
Vector的查找速度肯定没Map快啊,所以要选择合适的数据结构。
可参考:C++——std::Map。