【LeetCode Hot100】和为 K 的子数组 | 前缀和+哈希表,Java实现!图解+代码,小白秒懂!

LeetCode 560题:前缀和+哈希表解法

💡 【LeetCode Hot100】和为 K 的子数组 | 前缀和+哈希表,Java实现!图解+代码,小白秒懂!

✏️ 题目链接: 560. 和为 K 的子数组


📌 题目描述

给定一个整数数组 nums 和一个整数 k,请找到该数组中和为 k 的连续子数组的个数。

示例:

输入:nums = [1,1,1], k = 2
输出:2
解释:连续子数组 [1,1][1,1] 的和均为 2

🧠 解题思路

❗ 核心难点

如何高效计算所有和为 k 的子数组?


方法:前缀和 + 哈希表(黄金思路)✨

关键步骤:

  1. 前缀和定义preSum[i] 表示前 i 个元素的和。
  2. 哈希表记录:存储前缀和出现的次数,用于快速查询。
  3. 遍历数组
    • 计算当前前缀和 sum
    • 检查哈希表中是否存在 sum - k,存在则累加次数。
    • 将当前前缀和存入哈希表。

🎨 图解示例

输入数组:

nums = [1, 2, 3], k = 3

步骤1:初始化

preSumMap = {0:1} // 初始前缀和为0,出现1次
sum = 0, count = 0

步骤2:遍历数组

元素1: sum=1 → sum-k=1-3=-2 → 不在map → count=0 → map更新为 {0:1, 1:1}
元素2: sum=3 → sum-k=0 → map中存在0 → count+=1 → count=1 → map更新为 {0:1, 1:1, 3:1}
元素3: sum=6 → sum-k=3 → map中存在3 → count+=1 → count=2 → map更新为 {0:1, 1:1, 3:1, 6:1}

结果:

count = 2(对应子数组 [1,2] 和 [3])

🚀 代码实现

import java.util.HashMap;
import java.util.Map;

class Solution {
    public int subarraySum(int[] nums, int k) {
        Map<Integer, Integer> preSumMap = new HashMap<>();
        preSumMap.put(0, 1); // 初始化前缀和为0的次数为1
        int sum = 0; // 当前前缀和
        int count = 0; // 结果计数器

        for (int num : nums) {
            sum += num; // 计算当前前缀和
            // 检查是否存在 sum - k 的前缀和
            if (preSumMap.containsKey(sum - k)) {
                count += preSumMap.get(sum - k);
            }
            // 更新当前前缀和的出现次数
            preSumMap.put(sum, preSumMap.getOrDefault(sum, 0) + 1);
        }
        return count;
    }
}

💡 复杂度分析

  • 时间复杂度:O(n) → 只需遍历数组一次。
  • 空间复杂度:O(n) → 哈希表存储前缀和,最坏情况下需要存储 n 个不同前缀和。

🌟 总结

  • 前缀和核心思想:通过差值快速定位子数组范围。
  • 哈希表优化:避免重复计算,将时间复杂度从 O(n²) 降至 O(n)。
  • 适用场景:连续子数组求和问题、统计特定和的出现次数。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值