Leetcode Hot100 子串
部分解题思路借鉴了leetcode官方解集
560.子数组和等于 K 的个数¶
设计思路:先获取子数组,再计算子数组中的值是否为k
枚举法解题¶
public class Solution {
public int subarraySum(int[] nums, int k) {
int count = 0; // 统计子数组的个数
for (int start = 0; start < nums.length; ++start) {
int sum = 0;
for (int end = start; end >= 0; --end) {
// 子循环用于遍历子数组,相当于获取以start为终点的子数组集
// 从start开始,向左遍历,计算子数组的和
sum += nums[end];
if (sum == k) {
count++; // 计数,然后每次子循环结束后重置
}
}
}
return count;
}
}
前缀和哈希表解题¶
public class Solution {
public int subarraySum(int[] nums, int k) {
int count = 0, pre = 0;
HashMap < Integer, Integer > mp = new HashMap < > ();
mp.put(0, 1); // 初始化哈希表,前缀和为0的次数为1
for (int i = 0; i < nums.length; i++) {
pre += nums[i]; // 计算遍历到当前i位置的前缀和
if (mp.containsKey(pre - k)) {
// 此处就是求使得 pre[i] - pre[j] = k 的 pre[j] 的个数
// 从哈希表中获取次数并更新count
count += mp.get(pre - k);
}
mp.put(pre, mp.getOrDefault(pre, 0) + 1);
// 统计前缀和出现次数并更新哈希表
}
return count;
}
}
因此我们可以得到,下标排序靠后的前缀和 - 排序靠前的前缀和 = 二者之间的子数组之和 哈希表用于存储前缀和的出现次数。
这里的理解有点复杂,首先我们要知道,我们现在要找到的是可以得到k值的一个子数组
其次,假设存在一个子数组是[j+1,.... ,i]之间,那么就存在sum(j+1, i) = pre[i] - pre[j] 而我们要找的是sum(j+1, i) = k,等于k的子数组个数 即求 pre[i] - pre[j] = k,等于k的子数组个数 所以可以将 求 使子数组和为k的个数 的问题 转化为 当 当前遍历的前缀和为pre[i]时 使得 pre[i] - pre[j] = k 的 pre[j] 的个数