news 2026/3/1 3:01:44

LeetCode 热题100:和为 K 的子数组(Java 实现详解)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 热题100:和为 K 的子数组(Java 实现详解)

LeetCode 热题100:和为 K 的子数组(Java 实现详解)

本文将深入剖析 LeetCode 第560题《和为 K 的子数组》,从暴力枚举到前缀和 + 哈希表优化,全面讲解如何在 O(n) 时间内高效统计连续子数组和为 k 的个数。内容涵盖解题思路、代码实现、复杂度分析、面试高频问题及实际应用场景。


📌 原题回顾

题目描述
给你一个整数数组nums和一个整数k,请你统计并返回该数组中和为k的子数组的个数

子数组:数组中元素的连续非空序列

示例

输入:nums = [1,1,1], k = 2 输出:2 解释:[1,1](索引0~1)和 [1,1](索引1~2) 输入:nums = [1,2,3], k = 3 输出:2 解释:[1,2] 和 [3]

约束条件

  • 1 <= nums.length <= 2 * 10^4
  • -1000 <= nums[i] <= 1000
  • -10^7 <= k <= 10^7

🔍 原题分析

本题要求统计所有连续子数组中和等于 k 的数量

关键点:

  • 子数组必须连续
  • 元素可正可负,因此不能提前终止(负数可能使后续和再次等于 k);
  • 暴力法时间复杂度高,需寻找更优解。

常见误区:

  • 误用滑动窗口(仅适用于全正数或单调性场景);
  • 忽略前缀和中“0”的初始状态。

💡 答案构思

方法一:暴力枚举(O(n²))

对每个起始位置i,向左累加(或向右),检查是否存在子数组和为k

虽然可行,但面对n=2e4时,操作次数高达 2e8,可能超时。

方法二:前缀和 + 哈希表(O(n))✅ 推荐

核心思想
  • 定义前缀和prepre[i] = nums[0] + nums[1] + ... + nums[i]
  • 若存在子数组nums[j..i]满足sum = k,则:
    pre[i] - pre[j-1] = k ⇒ pre[j-1] = pre[i] - k
  • 因此,对于当前前缀和pre,只需知道之前有多少个前缀和等于pre - k
关键技巧
  • 使用HashMap记录每个前缀和出现的次数
  • 初始化map.put(0, 1):表示前缀和为 0 出现 1 次(对应空子数组,用于处理从索引 0 开始的子数组)。

✅ 完整答案(Java)

方法一:暴力枚举(不推荐,仅作对比)

publicclassSolution{publicintsubarraySum(int[]nums,intk){intcount=0;for(intstart=0;start<nums.length;start++){intsum=0;for(intend=start;end>=0;end--){sum+=nums[end];if(sum==k){count++;}}}returncount;}}

方法二:前缀和 + 哈希表(最优解)

importjava.util.HashMap;publicclassSolution{publicintsubarraySum(int[]nums,intk){intcount=0;intpre=0;// 当前前缀和HashMap<Integer,Integer>map=newHashMap<>();map.put(0,1);// 重要!前缀和为0出现1次(空子数组)for(intnum:nums){pre+=num;// 查找是否存在 pre - kif(map.containsKey(pre-k)){count+=map.get(pre-k);}// 更新当前前缀和的出现次数map.put(pre,map.getOrDefault(pre,0)+1);}returncount;}}

🧠 代码分析

  • map.put(0, 1):这是最容易忽略的点!
    例如nums = [3], k = 3,当pre = 3时,需要pre - k = 0,若 map 中没有 0,则会漏掉这个解。
  • 累加顺序:先查pre - k,再更新map,避免将当前前缀和自身计入(防止 j > i)。
  • 负数支持:由于允许负数,前缀和可能重复、递减,哈希表能正确处理。

⏱️ 时间复杂度 & 空间复杂度分析

方法时间复杂度空间复杂度说明
暴力枚举O(n²)O(1)双重循环,内层累加 O(1)
前缀和 + 哈希表O(n)O(n)单次遍历,哈希表最坏存 n 个不同前缀和

n = 2e4时,O(n) 与 O(n²) 性能差距巨大,后者可能超时。


❓ 问题解答(FAQ)

Q1:为什么不能用滑动窗口?
A:滑动窗口要求“窗口扩大时和单调增加”,但本题含负数,窗口扩大后和可能变小,无法保证单调性。

Q2:如果 k 很大(如 1e9),会影响哈希表吗?
A:不会。哈希表 key 是前缀和(int 范围内),与 k 大小无关,只与pre - k是否存在于 map 中有关。

Q3:能否用数组代替 HashMap?
A:不行。前缀和范围可能很大(如[-2e7, 2e7]),无法用数组索引,且有负数。


🚀 优化思路

本题的 O(n) 解法已是最优,但可注意以下工程细节:

  1. 使用getOrDefault避免 NPE;
  2. 避免重复计算pre - k,可缓存为变量;
  3. 考虑溢出:虽然题目未要求,但若nums[i]极大,可用longpre
// 防溢出版本(本题无需,但好习惯)longpre=0;Map<Long,Integer>map=newHashMap<>();

📚 数据结构与算法基础知识点回顾

知识点说明
前缀和(Prefix Sum)快速计算任意区间和:sum[i..j] = pre[j] - pre[i-1]
哈希表(HashMap)O(1) 插入/查询,用于记录历史状态频次
子数组 vs 子序列子数组必须连续,子序列可不连续
初始化边界条件map.put(0, 1)是解决“从头开始”子数组的关键

💬 面试官提问环节(模拟)

Q:如果数组全是正数,能否用双指针?
A:可以!此时前缀和单调递增,可用滑动窗口:

  • 若当前和 < k,右指针右移;
  • 若当前和 > k,左指针右移;
  • 若等于 k,计数并移动指针。

Q:如何修改代码以返回所有满足条件的子数组(而不仅是数量)?
A:需记录每个前缀和对应的索引列表,当pre - k存在时,遍历其索引列表生成子数组。但空间复杂度上升。

Q:如果要求子数组长度至少为 L,怎么改?
A:可在哈希表中存储<前缀和, Deque<索引>>,每次查询时只取索引 ≤ i - L 的项。


🛠️ 实际开发中的应用场景

  1. 金融交易系统:统计某段时间内累计收益等于目标值的交易区间;
  2. 日志分析:查找连续请求耗时总和等于阈值的时间窗口;
  3. 物联网数据流:检测传感器数据中是否存在累计偏差为 k 的时间段;
  4. 游戏开发:判断玩家连续得分是否达到某个奖励阈值。

🔗 相关题目推荐

题号题目关联点
LeetCode 560本题
LeetCode 523连续的子数组和前缀和 + 同余定理
LeetCode 525连续数组前缀和 + 0/1 平衡
LeetCode 974和可被 K 整除的子数组前缀和 + 模运算
LeetCode 724寻找数组的中心下标前缀和应用

📝 总结与延伸

本题是前缀和 + 哈希表的经典应用,展示了如何将 O(n²) 问题优化至 O(n)。

核心思想提炼:

  • 将“区间和”问题转化为“前缀和差值”问题;
  • 利用哈希表记录历史状态,实现 O(1) 查询;
  • 正确处理边界条件(如前缀和为 0)。

延伸思考:

  • 若数组动态更新(如支持单点修改),可使用树状数组(Fenwick Tree)线段树维护前缀和;
  • 若 k 为变量(多次查询),可预处理所有前缀和并排序,用二分查找(但本题 k 固定,哈希更优)。

掌握前缀和思想,你就拥有了处理“区间和”类问题的利器!

建议动手实现两种方法,对比性能差异,加深理解。

👉 如果你觉得本文对你有帮助,欢迎点赞、收藏、评论!也欢迎关注我的 CSDN 主页,获取更多高质量算法解析。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/26 21:33:17

为什么你的PHP缓存总失效?Redis集群配置常见错误大盘点

第一章&#xff1a;为什么你的PHP缓存总失效&#xff1f;Redis集群配置常见错误大盘点在高并发Web应用中&#xff0c;PHP结合Redis集群实现缓存是提升性能的常用手段。然而&#xff0c;许多开发者发现缓存频繁失效&#xff0c;响应延迟升高&#xff0c;问题往往出在Redis集群的…

作者头像 李华
网站建设 2026/2/22 15:17:37

【PHP智能家居温度控制实战】:手把手教你打造可远程调控的温控系统

第一章&#xff1a;PHP智能家居温度控制概述随着物联网技术的快速发展&#xff0c;智能家居系统逐渐成为现代家庭的重要组成部分。其中&#xff0c;温度控制作为提升居住舒适度与能源效率的核心功能之一&#xff0c;受到广泛关注。PHP 作为一种广泛应用于Web开发的脚本语言&…

作者头像 李华
网站建设 2026/2/20 10:47:42

【从入门到上线】:PHP开发者必备的MQTT网关部署6大避坑指南

第一章&#xff1a;PHP物联网网关与MQTT协议概述 在现代物联网&#xff08;IoT&#xff09;架构中&#xff0c;设备间的高效通信至关重要。PHP作为一种广泛使用的服务器端脚本语言&#xff0c;虽非传统意义上的实时通信首选&#xff0c;但通过合理设计可作为物联网网关的核心组…

作者头像 李华
网站建设 2026/2/28 23:37:08

2026自助网球馆的“美团核销”破局之路

夏日的热情&#xff0c;正从泳池蔓延到网球场。随着全民健身热潮与“精致运动”生活方式的兴起&#xff0c;自助网球馆——这种兼具灵活性、私密性与科技感的新业态&#xff0c;正成为都市运动爱好者的新宠。无需预约教练、自由安排时间、扫码即可入场&#xff0c;其便捷模式直…

作者头像 李华
网站建设 2026/2/25 3:23:59

服务器负载飙升?PHP视频流转码配置不当的6大征兆及修复方法

第一章&#xff1a;服务器负载飙升&#xff1f;PHP视频流转码配置不当的6大征兆及修复方法当服务器在处理视频流时突然出现CPU或内存使用率激增&#xff0c;往往与PHP后端调用转码工具的配置缺陷密切相关。以下是常见的六大异常表现及其解决方案。进程长时间挂起不退出 PHP通过…

作者头像 李华
网站建设 2026/2/24 7:01:03

TCL华星光电面板:HeyGem生成显示器色彩校准教学视频

TCL华星光电面板&#xff1a;HeyGem生成显示器色彩校准教学视频 在专业显示设备的使用现场&#xff0c;一个常见的问题反复出现——即便是配备了顶级OLED面板的TCL华星P系列显示器&#xff0c;用户依然无法稳定输出准确的色彩表现。问题不在于硬件本身&#xff0c;而在于“人”…

作者头像 李华