news 2026/4/16 3:15:19

从力扣560->974 掌握“前缀和 + 哈希表“

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从力扣560->974 掌握“前缀和 + 哈希表“

一. 核心痛点: 为什么暴力法必超时

当我们看到问题 要找和为k被k整除的连续子数组时 第一反应都是双层for循环

  • 时间复杂度: O(n^2)
  • 核心问题: 当数组长度达到10^5时 计算量高达100亿次 必爆TLE(超时)
  • 滑动窗口: 看到连续序列 也会想到使用滑动窗口 但是由于数据有正有负 不单调 故无法使用滑动窗口解决

二. 第一大神器: 前缀和

以560. 和为k的子数组为例

  1. 看到这道题目 直觉就是 往前找

当你站在数组中的某一个位置j时 你就想知道: 从那里(i)开始到我这儿(j) 和刚好为k?

笨办法就是一个一个往回数:

从j - 1到j吗?

从j - 2到j吗?..

这样计算量太大了

  1. 使用前缀和简化这个过程

计算每个位置的前缀和P

p[j]: 记录的是从起点到j位置的总距离

p[i - 1]: 记录的是从起点到i - 1位置的总距离

那么p[j] - p[i - 1]就是从i 到 j位置的距离如果这个距离等于k 那么[i, j]就是我们要找的子数组

三. 公式转化

k = p[j] - p[i - 1]

要转换为p[i - 1] = p[j] - k

为什么要进行转换???

因为当你遍历到 j 位置时 手里的已知量是 p[j]

为了找到符合条件的i

要回头一个个检查 当i = 0 1 2 …时 p[j] - p[i - 1] 是否等于k 这样做 时间复杂度又回到了O(n^2)

为解决这个问题 就引入了下一个神器哈希表

四. 第二大神器: 哈希表

构建哈希表时 key和value分别代表什么???

将想要快速找到的 设为key 要得到的结果 设为value

  • key: 目标的特征(560: 固定的差值 974: 特定的余数)
  • value:题目要求子数组个数 那么value就是特征出现的个数

**时间复杂度: ** 在unordered_map中 查找key的效率为O(1) 所以可以将整体时间复杂度降为O(n)

五. 小陷阱

  1. 在定义完unordered_map后 要进行 map[0] = 1的操作

主要为了解决: 以数组头为起点的子数组不被忽略

  • 场景一: nums = [5 …] k = 5

走到下标0 sum = 5

sum - k = 5 - 5 = 0

如果不初始化map[0] = 1 那么[5]这个正确的子数组答案就被跳过了

  • 场景二: nums = [1, 2, 2, …] k = 5

走到下标2时 sum = 5

sum - k = 5 -5 = 0

然后回哈希表里查找map[0] 发现查无此数 那么这个正确的子数组也被跳过了

六. 完整代码

560 和为k的子数组
classSolution{public:intsubarraySum(vector<int>&nums,intk){std::unordered_map<int,int>umap;umap[0]=1;intsum=0;intans=0;for(intx:nums){// 计算前缀和sum+=x;// 在哈希表内查找差值是否存在ans+=umap[sum-k];// 插入前缀和umap[sum]++;}returnans;}};
974 和可被k整除的子数组

在 C++ 中,负数取余(如-1 % 5)结果仍为负数。为了让哈希表的 Key 统一,我们使用(sum % k + k) % k将其余数强制“转正”

classSolution{public:intsubarraysDivByK(vector<int>&nums,intk){// 区间和 子数组 优先考虑前缀和unordered_map<int,int>umap;umap[0]=1;intsum=0;intcount=0;for(intx:nums){// 计算前缀和sum+=x;// 在前面找目标值 并将结果模值转换为正数count+=umap[(sum%k+k)%k];// 要查找什么 就要插入什么umap[(sum%k+k)%k]++;}returncount;}};
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 3:14:22

MySQL如何实现不停机数据平滑迁移_利用主从复制与流量切换

主从复制难以完全撑住实时写入压力&#xff0c;因从库回放依赖单线程或有限并行线程&#xff0c;高并发下Seconds_Behind_Master易持续上涨&#xff1b;大事务必然导致延迟飙升&#xff0c;单表小事务在并行复制下可基本跟上。主从复制能撑住实时写入压力吗MySQL主从复制本身不…

作者头像 李华
网站建设 2026/4/16 3:09:10

自动化测试:PO模式介绍及案例

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快PO&#xff08;Page Object&#xff09;设计模式是一种面向对象( 页面对象&#xff09;的设计模式&#xff0c;将测试对象及单个的测试步骤封装在每个Page对象以pag…

作者头像 李华
网站建设 2026/4/16 3:09:10

基于Raspberry Pi和OpenCV的家庭智能监控系统

智能家居新选择&#xff1a;树莓派监控系统 在科技飞速发展的今天&#xff0c;家庭安全监控已成为现代生活的刚需。基于Raspberry Pi&#xff08;树莓派&#xff09;和OpenCV的智能监控系统&#xff0c;凭借低成本、高灵活性和强大图像处理能力&#xff0c;成为DIY爱好者和技术…

作者头像 李华
网站建设 2026/4/16 3:08:08

LED电路的设计原理

LED电路的设计原理核心是 “电流控制”​ &#xff0c;因为LED是电流驱动型器件。其设计目标是为LED提供稳定、合适的正向工作电流&#xff0c;使其正常发光且不被损坏。一、 最核心的设计&#xff1a;限流LED的电压-电流特性曲线非常陡峭&#xff0c;电压微小变化会引起电流巨…

作者头像 李华