目录

一、560.和为K的⼦数组
题目链接:560.和为K的⼦数组
题目描述:
题目解析:
- 求数组中子串的和为k的个数。
1.1 前缀和
解题思路:
- 假设已经创建好了一个前缀和数组dp,我们使用前缀和的时候,判断从0到 i 位置的和为k的子数组个数,只需要在dp下标[ 0 , i - 1 ]中找dp元素值为dp[ i ] - k的个数即可。
- 所以我们使用一个容器hash表来存储从0 到 i - 1的前缀和的个数,关键字key就是前缀和,values就是次数。
- 细节处理:
-
- 我们不需要真的使用前缀和数组,只需要遍历原数组时,用一个变量记录遍历过的元素和即可。
-
- 当该前缀和就是k的时候,我们上面条件没有考虑,所以我们还要先放入(0,1)表示这种情况。
解题代码:
//时间复杂度:O(n)
//空间复杂度:O(n)
class Solution {
public int subarraySum(int[] nums, int k) {
Map<Integer,Integer> hash = new HashMap<>();
hash.put(0,1);
int sum = 0;
int ret = 0;
for(int i = 0; i < nums.length; i++) {
sum += nums[i];
ret += hash.getOrDefault(sum-k,0);
hash.put(sum, hash.getOrDefault(sum,0)+1);
}
return ret;
}
}
1.2 暴力枚举
解题思路:
- 直接使用两层for循环,将每一种可能枚举出来。
解题代码:
//时间复杂度:O(n^2)
//空间复杂度:O(1)
class Solution {
public int subarraySum(int[] nums, int k) {
int ret = 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) {
ret++;
}
}
}
return ret;
}
}
二、974.和可被K整除的⼦数组
题目链接:974.和可被K整除的⼦数组
题目描述:
题目解析:
- 跟上一道题一样的思路,只不过这个是求能被整除的个数而已。
2.1 前缀和
解题思路:
- 同余定理:如果(a - b)% p == 0 那么a % p 和b % p值相等。
- Java中负数对正数取余修正:在Java中负数对正数取余余数会是负数,修正方法就是:(a % p + p)% p
- 使用hash表将i下标前的每一个前缀和与k的余数存入。
- 再看前面前缀和与当前 前缀和的余数相同的个数即可。
- 当[0 , i]本身前缀和余数为0的时候,就是一个符合条件的子数组。
解题代码