题目
https://leetcode-cn.com/problems/subarray-sum-equals-k/
方法一:前缀和 + 哈希表优化
分析
0…i的和表示为:pre[i]
j…i的和表示为:pre[i]-pre[j-1]
满足条件的j…i的和为:k=pre[i]-pre[j-1]→pre[j-1]=pre[i]-k
建立哈希表<和,出现次数>,那么pre[i]-k的次数就可以在O(1)时间内得到。
代码
class Solution {
public int subarraySum(int[] nums, int k) {
HashMap<Integer,Integer> map=new HashMap<>();
int pre=0;
int count=0;
map.put(0,1);//和为0,有一种方法
for(int i=0;i<nums.length;i++){
pre+=nums[i];
if(map.containsKey(pre-k)){
count+=map.get(pre-k);
}
map.put(pre,map.getOrDefault(pre,0)+1);
}
return count;
}
}
复杂度
时间复杂度:O(n),其中 n为数组的长度。我们遍历数组的时间复杂度为O(n),中间利用哈希表查询删除的复杂度均为O(1),因此总时间复杂度为 O(n)。
空间复杂度:O(n),其中 n 为数组的长度。哈希表在最坏情况下可能有 n 个不同的键值,因此需要 O(n) 的空间复杂度。
结果
方法二:我原来的代码
一顿操作猛如虎,提交击败百分五
class Solution {
public int subarraySum(int[] nums, int k) {
//sum(i,j)=sum(0,j)-sum(0,i)
int[] sum=new int[nums.length];
sum[0]=nums[0];
for(int i=1;i<nums.length;i++){
sum[i]=nums[i]+sum[i-1];
}
int count=0;
for(int i=0;i<nums.length;i++){
for(int j=i;j<nums.length;j++){
int s=sum[j]-sum[i]+nums[i];
if(s==k){
count++;
}
}
}
return count;
}
}