题目描述
- 第一道前缀和题目~
思路 & 代码
暴力法 O(
n
2
n^2
n2)
class Solution {
public int subarraySum(int[] nums, int k) {
int ans = 0;
for(int i = 0; i < nums.length; i++){
int temp = 0;
for(int j = i; j >= 0; j--){
temp += nums[j];
if(temp == k){
ans++;
}
}
}
return ans;
}
}
前缀和 + 哈希表 O(n)
- 连续子数组值 = preNum[j] - preNum[i],很巧妙
- 一次遍历动态哈希,一边维护一边找~
class Solution {
public int subarraySum(int[] nums, int k) {
Map<Integer, Integer> hashmap = new HashMap<>();
hashmap.put(0, 1);
int preSum = 0;
int ans = 0;
for(int num : nums){
preSum += num;
if(hashmap.containsKey(preSum - k)){
ans += hashmap.get(preSum - k);
}
hashmap.put(preSum, hashmap.getOrDefault(preSum, 0) + 1);
}
return ans;
}
}
二刷
- 才发现对前缀和这个概念不是很熟悉…
- 说实话我觉得这题代码相对抽象,有必要用点简单例子人脑走一遍:
- 比如 map.put(0, 1) 这一行(比如[1, 1], 2。没有这一行就直接得 0 了)
- (虽然图片有点丑,但是请勉强看看吧 = = )
- 这么个意思,累加 sum,如果发现当前 sum,在 - k 之后的值,曾经出现过,那么说明存在图中连续的橙色子数组,满足累加和 = k!
class Solution {
public int subarraySum(int[] nums, int k) {
Map<Integer, Integer> map = new HashMap<>();
map.put(0, 1);
int sum = 0, res = 0;
for(int temp : nums) {
sum += temp;
if(map.containsKey(sum - k)) {
res += map.get(sum - k);
}
map.put(sum, map.getOrDefault(sum, 0) + 1);
}
return res;
}
}