思路:
1.前缀和
2.前缀和+哈希表
代码:
前缀和
class Solution {
public int subarraySum(int[] nums, int k) {
int n=nums.length;
int sum=0;
int[] dp=new int[n+1];
dp[0]=0;
//计算前缀和
for(int i=1;i<=n;i++){
//dp[i]代表不包括当前数nums[i]的前缀和
dp[i]=dp[i-1]+nums[i-1];
}
for(int left=0;left<n;left++){
for(int right=left;right<n;right++){
if(dp[right+1]-dp[left]==k){
sum++;
}
}
}
return sum;
}
}
前缀和+哈希表:
class Solution {
public int subarraySum(int[] nums, int k) {
int n=nums.length;
int preSum=0;
int count=0;
Map<Integer,Integer> map=new HashMap<>();
//初始化:前缀和为0,有1个数字
map.put(0,1);
for(int num:nums){
preSum+=num;
if(map.containsKey(preSum-k)){
//注意这里,并不是+1
//利于了公式j-i==k的变化-->j-k==i
count+=map.get(preSum-k);
}
map.put(preSum,map.getOrDefault(preSum,0)+1);
}
return count;
}
}
分解:
前缀和:
1)先计算出所有前缀和保存在dp数组中,用dp[right]-dp[left]==k得出一个解
前缀和+哈希表:
1)因为只需要计算个数,而不需要计算具体的解,可以利于哈希表来把时间复杂度降低到O(N)
2)注意这里,并不是+1,利用了公式j-i==k的变化-->j-k==i
count+=map.get(preSum-k);
复杂度分析:
前缀和:
时间复杂度:O(N^2)双重循环
空间复杂度:O(N)数组
前缀和+哈希表:
时间复杂度:O(N)
空间复杂度:O(N)