试题
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:
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(int[] nums, int k) {
int res = 0;
int[] cumsum = new int[nums.length+1];
for(int i=1; i<=nums.length; i++){
cumsum[i] = cumsum[i-1] + nums[i-1];
}
for(int i=0; i<=nums.length; i++){
for(int j=i+1; j<=nums.length; j++){
if(cumsum[j]-cumsum[i]==k)
res++;
}
}
return res;
}
}
暴力求解的方式是指定起点和终点,一种优化方式是每次我们指定一个起点,然后从前往后把所有的以该起点为起点的子数组都统计一遍。
class Solution {
public int subarraySum(int[] nums, int k) {
int res = 0;
for(int i=0; i<nums.length; i++){
int sum = 0;
for(int j=i; j<nums.length; j++){
sum += nums[j];
if(sum==k){
res += 1;
}
}
}
return res;
}
}
累计求和优化方式:首先我们明白累积求和是求0到当前位置的和sum,那么sum-k代表的就是从当前位置累积和减去k,也就是以当前位置为尾点的满足子数组和为k的起点位置累积和。我们使用hashmap统计之前有多少累积和满足要求。
class Solution {
public int subarraySum(int[] nums, int k) {
int res = 0, sum=0;
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0,1);
for(int i=0; i<nums.length; i++){
sum += nums[i];
if(map.containsKey(sum-k)){
res += map.get(sum-k);
}
map.put(sum, map.getOrDefault(sum, 0)+1);
}
return res;
}
}