🔥近津薪荼: [个人主页] 🎬个人专栏: 《近津薪荼的算法日迹》 《Linux操作系统及网络基础知识分享》 《c++基础知识详解》 《c语言基础知识详解》 ✨不要物化,矮化,弱化,钝化自己,保持锋芒,不要停止学习 这个世界上只有两个人真正在注意着你 八岁的你,和八十岁的你, 他们此刻正在注视着你, 一个希望你 勇敢开始 ,一个希望你 不留遗憾
1.上期参考代码
cpp
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
unordered_map<int,int> hash;
hash[0]=1;//初始化hash
int sum=0,ret=0;
for(int i=0;i<nums.size();i++)
{
sum+=nums[i];
ret+=hash[sum-k];//先汇总
hash[sum]++;//后将新的和加入,目的是规避k=0的错判
}
return ret;
}
};
2.本期知识点导图

3.本期要讲解的题目是
和可被 K 整除的子数组
这是一道往年的蓝桥杯真题,思路和上一题大相径庭
大家尝试看完解析之后,能不能自己吧代码写出来~

要点:
- 本质关键的还是子数组求和方法
4.解题
4.1 暴力解法:
暴力枚举,时间复杂度O(N3)
4.2优解
由于数组的元素有负数和0,通上一期的题目一样,不可使用双指针算法优化
同样的
数组求和,考虑前缀和算法
接着根据条件,在前n项和的变式上做文章
这里就要给大家补充
两个知识点了
- 同余定理:
若两个整数 a 和 b 除以正整数 k 所得的余数相同,则称 a 和 b 对模 k 同余
同余的两个数有如下性质:

- cpp中的模运算%
cpp中的%的结果的正负号看的是根据被模数来的,我们要求的事取余的结果,余数必须是正数,所以要进行修正:加上一个模即可,然后考虑到要和正数的情况相统一,我们得到以下的求余数的公式:((a%b)+k)&k,得到的结果就是我们想要的正数余数
补充完这两个知识点,我想大家应该也能想到这题的思路了吧
利用同于定理,将目标值映射到前缀和数组上来

细节
整体细节和上期相同,只有第三点:
当a=b时,a-b=0,满足条件,但是我们每次只统计到前缀和数组i-1及之前位置元素的余数r,这种情况在i位置,统计不到,所以要给hash[0%k]一个初始值1。
代码逻辑
- 初始化hash,ret,sum
- 进入循环
- 求i位置前缀和
- 求sum的余数r
- 汇总哈希表i-1及之前位置等于r的前缀和的个数
- i位置的前缀和进入哈希表
5.下期要讲解的题目是:
连续数组
6.嗟食
如果小编写的内容对佬有帮助,还请大佬点点三连加关注哦 
佬的支持就是我前进的最大动力
~
期待与佬的再次相遇~