news 2026/7/7 19:15:59

【每日算法】LeetCode 560. 和为 K 的子数组

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【每日算法】LeetCode 560. 和为 K 的子数组

对前端开发者而言,学习算法绝非为了“炫技”。它是你从"页面构建者"迈向"复杂系统设计者"的关键阶梯。它将你的编码能力从"实现功能"提升到"设计优雅、高效解决方案"的层面。从现在开始,每天投入一小段时间,结合前端场景去理解和练习,你将会感受到自身技术视野和问题解决能力的质的飞跃。------ 算法:资深前端开发者的进阶引擎

LeetCode 560. 和为 K 的子数组:前缀和的精妙应用

1. 题目描述

给你一个整数数组nums和一个整数k,请你统计并返回该数组中和为k的连续子数组的个数。

示例 1:

输入:nums = [1,1,1], k = 2 输出:2 解释:[1,1] 与 [1,1] 为两种不同的情况(注意:虽然值相同,但索引位置不同)

示例 2:

输入:nums = [1,2,3], k = 3 输出:2 解释:[1,2] 和 [3]

约束条件:

  • 数组长度范围:1 <= nums.length <= 2 * 10⁴
  • 数组元素范围:-1000 <= nums[i] <= 1000
  • k 的范围:-10⁷ <= k <= 10⁷

2. 问题分析

2.1 问题核心

这个问题要求统计数组中连续子数组的和等于给定值k的个数。这是一个典型的子数组求和问题,需要特别注意:

  • 子数组必须是连续的
  • 数组元素可以是负数,这增加了问题的复杂性
  • 需要考虑空数组吗?题目没有明确说明,但根据示例,至少需要包含一个元素

2.2 前端视角的类比

在前端开发中,类似的问题场景包括:

  • 统计页面中连续点击次数达到特定阈值的情况
  • 计算用户行为序列中特定模式的出现次数
  • 分析性能监控数据中连续时间段内指标达标的情况

3. 解题思路

3.1 思路演进

3.1.1 暴力枚举法

最直观的想法是枚举所有可能的子数组,计算它们的和,统计等于k的数量。

3.1.2 前缀和优化

暴力法的时间复杂度为 O(n²),对于 2×10⁴ 的数据量会超时。我们需要更高效的方法。

前缀和(Prefix Sum)概念
前缀和是一种预处理技术,通过预先计算并存储数组的前缀和,可以在 O(1) 时间内计算任意子数组的和。

定义前缀和数组preSum,其中preSum[i]表示nums[0] + nums[1] + ... + nums[i-1]的和。

那么子数组nums[i..j]的和可以表示为:

sum(nums[i..j]) = preSum[j+1] - preSum[i]
3.1.3 哈希表优化

对于每个j,我们需要找到有多少个i满足preSum[i] = preSum[j+1] - k。使用哈希表可以在 O(1) 时间内完成查找。

核心公式

preSum[j+1] - preSum[i] = k => preSum[i] = preSum[j+1] - k

3.2 复杂度分析

方法时间复杂度空间复杂度是否推荐
暴力枚举O(n²)O(1)不推荐,会超时
前缀和+哈希表O(n)O(n)推荐,最优解

4. 各思路代码实现

4.1 暴力枚举法(不推荐,仅用于理解)

/** * 暴力枚举法 * @param {number[]} nums * @param {number} k * @return {number} */varsubarraySumBruteForce=function(nums,k){letcount=0;constn=nums.length;for(leti=0;i<n;i++){letsum=0;for(letj=i;j<n;j++){sum+=nums[j];if(sum===k){count++;}}}returncount;};

4.2 前缀和+哈希表法(最优解)

/** * 前缀和+哈希表法(最优解) * @param {number[]} nums * @param {number} k * @return {number} */varsubarraySum=function(nums,k){// 哈希表:键为前缀和,值为该前缀和出现的次数constmap=newMap();// 初始化:前缀和为0出现了1次(空数组的情况)map.set(0,1);letcount=0;letprefixSum=0;for(leti=0;i<nums.length;i++){// 计算当前前缀和prefixSum+=nums[i];// 如果存在某个前缀和等于 currentPrefixSum - k// 说明从那个位置到当前位置的子数组和为 kif(map.has(prefixSum-k)){count+=map.get(prefixSum-k);}// 更新当前前缀和出现的次数map.set(prefixSum,(map.get(prefixSum)||0)+1);}returncount;};

4.3 带详细注释的版本(便于理解)

/** * 前缀和+哈希表法(详细注释版) * @param {number[]} nums * @param {number} k * @return {number} */varsubarraySumWithComments=function(nums,k){// 哈希表:存储前缀和及其出现次数// 为什么需要这个哈希表?// 我们要找的是:prefixSum[j] - prefixSum[i] = k// 即:prefixSum[i] = prefixSum[j] - k// 所以对于每个j,我们需要知道之前有多少个i满足这个条件constprefixSumCount=newMap();// 为什么要初始化前缀和为0出现了1次?// 考虑整个数组从开头到某个位置的子数组和为k的情况// 即:prefixSum[j] - 0 = k,这时候prefixSum[i]为0(i为-1,空数组)prefixSumCount.set(0,1);letcurrentSum=0;// 当前前缀和letresult=0;// 结果计数for(leti=0;i<nums.length;i++){// 计算到当前位置的前缀和currentSum+=nums[i];// 核心逻辑:如果存在一个前缀和等于 currentSum - k// 那么从那个位置到当前位置的子数组和就是k// 例如:nums = [1, 2, 3], k = 3// 当i=2时,currentSum = 6// currentSum - k = 3,如果之前出现过前缀和3,那么从那个位置到当前位置的和就是3consttarget=currentSum-k;if(prefixSumCount.has(target)){// 可能有多个位置的前缀和都等于target,所以都要加上result+=prefixSumCount.get(target);}// 更新当前前缀和的出现次数// 这里使用 || 0 来处理undefined的情况(如果该前缀和之前没出现过)prefixSumCount.set(currentSum,(prefixSumCount.get(currentSum)||0)+1);}returnresult;};

5. 各实现思路的复杂度、优缺点对比

5.1 对比表格

实现方法时间复杂度空间复杂度优点缺点适用场景
暴力枚举法O(n²)O(1)1. 思路直观简单
2. 不需要额外空间
1. 效率低下,n=20000时会超时
2. 不适合大数据量
小规模数据(n<1000)或教学演示
前缀和+哈希表O(n)O(n)1. 时间复杂度最优
2. 能处理包含负数的情况
3. 适合大规模数据
1. 需要额外O(n)空间
2. 逻辑相对复杂
大规模数据处理、生产环境推荐使用

5.2 详细分析

5.2.1 暴力枚举法
  • 时间复杂度分析

    • 外层循环:n次
    • 内层循环:平均n/2次
    • 总复杂度:O(n²)
    • 当n=20000时,操作次数约2亿次,明显超时
  • 空间复杂度:O(1),只使用了常数级别的额外空间

5.2.2 前缀和+哈希表法
  • 时间复杂度分析

    • 单次遍历数组:O(n)
    • 每次操作哈希表:平均O(1)
    • 总复杂度:O(n)
    • 当n=20000时,操作次数约2万次,效率极高
  • 空间复杂度

    • 最坏情况下,每个前缀和都不同,需要存储n个键值对
    • 空间复杂度:O(n)

6. 总结与前端应用场景

6.1 核心要点总结

  1. 前缀和思想:将子数组求和问题转化为前缀和之差的问题
  2. 哈希表优化:通过哈希表记录前缀和出现次数,实现O(1)时间查找
  3. 边界处理:注意初始化前缀和为0的情况(对应空子数组)
  4. 负数处理:由于数组元素可能为负数,不能使用双指针滑动窗口法

6.2 实际应用场景(前端视角)

6.2.1 性能监控与分析
// 监控连续时间段内API错误率达到阈值的情况consterrorRates=[0.1,0.2,0.05,0.3,0.15,0.25];constthreshold=0.5;// 统计连续时间段内错误率总和超过阈值的时间段数量functioncountErrorSpikes(errorRates,threshold){constmap=newMap();map.set(0,1);letcount=0;letprefixSum=0;for(letrateoferrorRates){prefixSum+=rate;if(map.has(prefixSum-threshold)){count+=map.get(prefixSum-threshold);}map.set(prefixSum,(map.get(prefixSum)||0)+1);}returncount;}
6.2.2 用户行为分析
// 分析用户连续操作序列// 例如:统计用户连续点击次数达到特定模式的情况constuserActions=['click','scroll','click','hover','click'];consttargetPattern=2;// 连续click的次数functioncountActionPatterns(actions,targetAction,targetCount){constmap=newMap();map.set(0,1);letcount=0;letcurrentStreak=0;for(letactionofactions){// 如果是目标行为,streak加1,否则重置为-1(或其他负值)currentStreak+=(action===targetAction?1:-1);// 查找是否有位置使得连续目标行为次数等于targetCountif(map.has(currentStreak-targetCount)){count+=map.get(currentStreak-targetCount);}map.set(currentStreak,(map.get(currentStreak)||0)+1);}returncount;}
6.2.3 数据处理与可视化
// 在数据可视化中,统计连续时间段内数据超过阈值的情况classDataAnalyzer{constructor(){this.prefixSumMap=newMap();}// 实时数据流处理processDataStream(dataStream,threshold){constresult=[];letprefixSum=0;letmap=newMap([[0,[-1]]]);// 存储前缀和及其出现的位置for(leti=0;i<dataStream.length;i++){prefixSum+=dataStream[i];// 查找满足条件的位置consttarget=prefixSum-threshold;if(map.has(target)){constpositions=map.get(target);for(letposofpositions){result.push([pos+1,i]);// 子数组的起始和结束索引}}// 更新哈希表if(!map.has(prefixSum)){map.set(prefixSum,[]);}map.get(prefixSum).push(i);}returnresult;}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 15:25:34

so-vits-svc F0预测器终极指南:快速上手与深度性能对比

在语音转换项目中&#xff0c;基频提取的准确性直接影响着最终音质的自然度和真实感。我们经常遇到这样的问题&#xff1a;为什么有些转换结果听起来机械感明显&#xff1f;为什么在复杂音频环境下转换效果大打折扣&#xff1f;这些问题的核心往往源于F0预测器的选择不当。今天…

作者头像 李华
网站建设 2026/7/7 7:04:50

5款QSS模板实战指南:零基础打造专业级Qt界面

5款QSS模板实战指南&#xff1a;零基础打造专业级Qt界面 【免费下载链接】QSS QT Style Sheets templates 项目地址: https://gitcode.com/gh_mirrors/qs/QSS 还在为Qt应用界面单调乏味而困扰吗&#xff1f;想要用最简单的方式让你的程序拥有商业级视觉效果吗&#xff1…

作者头像 李华
网站建设 2026/7/6 23:24:31

终极姿态搜索工具:快速实现人体动作识别的完整指南

终极姿态搜索工具&#xff1a;快速实现人体动作识别的完整指南 【免费下载链接】pose-search x6ud.github.io/pose-search 项目地址: https://gitcode.com/gh_mirrors/po/pose-search pose-search是一款基于现代Web技术的开源姿态搜索工具&#xff0c;能够实时识别图像中…

作者头像 李华
网站建设 2026/7/7 12:45:13

积木报表:5分钟上手免费企业级数据可视化工具

积木报表&#xff1a;5分钟上手免费企业级数据可视化工具 【免费下载链接】jimureport 「数据可视化工具&#xff1a;报表、大屏、仪表盘」积木报表是一款类Excel操作风格&#xff0c;在线拖拽设计的报表工具和和数据可视化产品。功能涵盖: 报表设计、大屏设计、打印设计、图形…

作者头像 李华
网站建设 2026/7/6 22:39:49

PostgreSQL pgvector扩展Windows安装终极指南

想要在Windows系统上为PostgreSQL数据库注入强大的向量搜索能力吗&#xff1f;pgvector扩展正是您需要的解决方案。本文将为您提供一套完整的PostgreSQL pgvector Windows安装教程&#xff0c;从环境准备到实战应用&#xff0c;助您轻松掌握这一AI时代的关键技术。 【免费下载链…

作者头像 李华