目录
[29. 和为k的子数组(medium)](#29. 和为k的子数组(medium))
[30. 和可被K整除的子数组(medium)](#30. 和可被K整除的子数组(medium))
[31. 连续数组(medium)](#31. 连续数组(medium))
[32. 矩阵区域和(medium)](#32. 矩阵区域和(medium))
29. 和为k的子数组(medium)
题目链接:
解题思路:
使用哈希表记录前缀和出现的次数。遍历数组,计算当前前缀和
sum,若sum - k在哈希表中存在,则累加其出现次数。
Java 代码:
java
class Solution {
public int subarraySum(int[] nums, int k) {
Map<Integer, Integer> hash = new HashMap<>();
hash.put(0, 1);
int sum = 0, ret = 0;
for (int x : nums) {
sum += x;
ret += hash.getOrDefault(sum - k, 0);
hash.put(sum, hash.getOrDefault(sum, 0) + 1);
}
return ret;
}
}
30. 和可被K整除的子数组(medium)
题目链接:
解题思路:
利用同余定理,若
(sum[i] - sum[j]) % K == 0,则sum[i] % K == sum[j] % K。使用哈希表记录每个余数出现的次数。
Java 代码:
java
class Solution {
public int subarraysDivByK(int[] nums, int k) {
Map<Integer, Integer> hash = new HashMap<>();
hash.put(0 % k, 1);
int sum = 0, ret = 0;
for (int x : nums) {
sum += x;
int r = (sum % k + k) % k;
ret += hash.getOrDefault(r, 0);
hash.put(r, hash.getOrDefault(r, 0) + 1);
}
return ret;
}
}
31. 连续数组(medium)
题目链接:
解题思路:
将
0视为-1,问题转化为寻找和为0的最长子数组。使用哈希表记录每个前缀和第一次出现的位置。
Java 代码:
java
class Solution {
public int subarraysDivByK(int[] nums, int k) {
Map<Integer, Integer> hash = new HashMap<>();
hash.put(0 % k, 1);
int sum = 0, ret = 0;
for (int x : nums) {
sum += x;
int r = (sum % k + k) % k;
ret += hash.getOrDefault(r, 0);
hash.put(r, hash.getOrDefault(r, 0) + 1);
}
return ret;
}
}
32. 矩阵区域和(medium)
题目链接:
解题思路:
使用二维前缀和,对于每个
(i,j),计算其周围k范围内的区域和。注意边界处理。
Java 代码:
java
class Solution {
public int findMaxLength(int[] nums) {
Map<Integer, Integer> hash = new HashMap<>();
hash.put(0, -1);
int sum = 0, ret = 0;
for (int i = 0; i < nums.length; i++) {
sum += nums[i] == 0 ? -1 : 1;
if (hash.containsKey(sum)) {
ret = Math.max(ret, i - hash.get(sum));
} else {
hash.put(sum, i);
}
}
return ret;
}
}