题目:
题解:
1. 题解一:暴力枚举
2. 题解二:前缀和 + 哈希表优化(首选)
代码:
1. 代码一:暴力枚举
public class code560 {
// 方法一: 暴力枚举
public int subarraySum(int[] nums, int k)
{
int count = 0;
for (int i = 0; i < nums.length; i++)
{
int sum = 0;
for (int j = i; j < nums.length; j++)
{
sum = sum + nums[j];
if (sum == k)
{
count++;
}
}
}
return count;
}
public static void main(String[] args) {
int[] nums = new int[]{1, 1, 1};
int k = 2;
code560 test = new code560();
int res = test.subarraySum(nums, k);
System.out.println(res);
}
}
2. 代码二:前缀和 + 哈希表优化(首选)
import java.util.*;
public class code560 {
// 方法二: 前缀和 + 哈希表优化
public int subarraySum(int[] nums, int k) {
// key为前缀和,value为它出现的次数,因为负数的存在,所以存在不同位置有着相同的前缀和
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, 1); // 如果出现前缀和与k相等的情况, 表示前缀和为0的连续子数组出现1次。
int sum = 0; // 前缀和
int count = 0; // 出现次数
for(int i = 0; i < nums.length; i++)
{
sum += nums[i];
// 如果正好有某个位置的前缀和与当前位置的前缀和差为K
// 则说明这个位置到当前位置中间数之和为K
if(map.containsKey(sum - k))
{
count += map.get(sum - k); // 出现几次则添加几次,因为从它们的位置出发到当前位置的和都为K
}
// 存入或刷新当前的前缀和与出现次数
map.put(sum, map.getOrDefault(sum, 0) + 1);
}
return count;
}
public static void main(String[] args) {
int[] nums = new int[]{1, 1, 1};
int k = 2;
code560 test = new code560();
int res = test.subarraySum(nums, k);
System.out.println(res);
}
}