《算法闯关指南:优选算法--前缀和》--29.和为k的子数组,30.和可被k整除的子数组

🎬 博主简介:

文章目录
- 前言:
- 29. 和为k的子数组
- 解法(前缀和+哈希表):
- 算法思路:
- C++算法代码:
- 算法总结&&笔记展示:
- 30. 和可被k整除的子数组
- 解法(前缀和+哈希表):
- 前置知识补充:
- 算法思路:
- C++算法代码:
- 算法总结&&笔记展示:
- 结尾:
前言:
聚焦算法题实战,系统讲解三大核心板块:优选算法:剖析动态规划、二分法等高效策略,学会寻找“最优解”。 递归与回溯:掌握问题分解与状态回退,攻克组合、排列等难题。 贪心算法:理解“局部最优”到“全局最优”的思路,解决区间调度等问题 内容以题带点,讲解思路与代码实现,帮助大家快速提升代码能力。
29. 和为k的子数组
题目链接:
560. 和为 K 的子数组 - 力扣(LeetCode)
题目描述:

题目示例:

解法(前缀和+哈希表):
算法思路:

设 i 为数组中的任意位置,用 sum[i] 表示 【0,i】区间内所有元素的和。
想知道有多少个【以 i 结尾的和为 k 的子数组】,就要找到有多少个起始位置为 x1,x2,x3……,使得【x,i】区间内所有元素的和 k 。那么【0,x】区间内的和是不是就是 sum[i]-k 了。于是问题就变成:
- 找到在
【0,i-1】区间内,有多少前缀和等于sum[i]-k的即可。
我们其实也不用真的初始化一个前缀和数组,因为我们只关心在 i 位置之前,有多少个前缀和等于 sum[i]-k 。因此,我们仅需要用一个哈希表,一边求当前位置的前缀和,一边存下之前每一种前缀和出现的次数。
C++算法代码:
class Solution {
public:int subarraySum(vector<int>& nums, int k) {unordered_map<int,int>hash;hash[0]=1;int sum=0,ret=0;for(auto x:nums){sum+=x;if(hash.count(sum-k)) ret+=hash[sum-k];hash[sum]++;}return ret;}
};
算法总结&&笔记展示:
笔记字有点丑,大家见谅:

30. 和可被k整除的子数组
题目链接:
974. 和可被 K 整除的子数组 - 力扣(LeetCode)
题目描述:

题目示例:

解法(前缀和+哈希表):
前置知识补充:
同余定理:
如果 (a-b) % n == 0,那么我们就可以得到一个结论:a % n == b%n。用文字叙述就是,如果两个数相减的差能够被n整除,那么这两个数对n取模的结果相同。
例如:(26-2) % 12 == 0,那么 26 % 12 == 2 % 12 == 2。
C++ 中负数取模的结果,以及修正【负数取模】的结果:
C++中关于负数的取模运算,结果是【把负数当成正数,取模之后的结果加上一个负号】。
例如:-1 % 3 = -(1 % 3) = -1- 因为有负数,为了防止发生【出现负数】的结果,以
(a % n + n) % n的形式输出保证为正
例如:-1 % 3=(-1 % 3 + 3)% 3 = 2
算法思路:
思路与上一题类似

设 i 为数组中的任意位置,用 sum[i] 表示 【0,i】区间内所有元素的和。
- 想知道有多少个【以
i为结尾的可被k整除的子数组】,就要找到有多少个起始位置为x1,x2,x3……,使得【x,i】区间内所有元素的和可被k整除。 - 设
【0,x-1】区间内所有元素之和等于a,【0,i】区间内所有元素的和等于b,可得(b - a)% k == 0。 - 由同余定理可得,
【0,x-1】区间与【0,i】区间内的前缀和同余。于是问题就变成:找到在【0,i-1】区间内,有多少前缀和的余数等于sum[i] % k的即可
我们不用真的初始化一个前缀和数组,因为我们只关心在 i 位置之前,有多少个前缀和等于 sum[i] % k。但是这个我们需要处理一下,确保不会为负数。因此,我们仅需用一个哈希表,一边求当前位置的前缀和,一边存下之前每一种前缀和出现的次数。
C++算法代码:
class Solution {
public:int subarraysDivByK(vector<int>& nums, int k) {unordered_map<int,int> hash;hash[0%k]=1;int sum=0,ret=0;for(auto x:nums){sum+=x;int r=(sum%k+k)%k;//修正后的余数if(hash.count(r)) ret+=hash[r];hash[r]++;}return ret;}
};
算法总结&&笔记展示:
笔记字有点丑,大家见谅:

结尾:
🍓 我是草莓熊 Lotso!若这篇技术干货帮你打通了学习中的卡点:
👀 【关注】跟我一起深耕技术领域,从基础到进阶,见证每一次成长
❤️ 【点赞】让优质内容被更多人看见,让知识传递更有力量
⭐ 【收藏】把核心知识点、实战技巧存好,需要时直接查、随时用
💬 【评论】分享你的经验或疑问(比如曾踩过的技术坑?),一起交流避坑
🗳️ 【投票】用你的选择助力社区内容方向,告诉大家哪个技术点最该重点拆解
技术之路难免有困惑,但同行的人会让前进更有方向~愿我们都能在自己专注的领域里,一步步靠近心中的技术目标!
结语:聚焦算法题实战,系统讲解三大核心板块:优选算法:剖析动态规划、二分法等高效策略,学会寻找“最优解”。 递归与回溯:掌握问题分解与状态回退,攻克组合、排列等难题。 贪心算法:理解“局部最优”到“全局最优”的思路,解决区间调度等问题 内容以题带点,讲解思路与代码实现,帮助大家快速提升代码能力。
✨把这些内容吃透超牛的!放松下吧✨ ʕ˘ᴥ˘ʔ づきらど

