【优选算法必刷100题】第029-030题(前缀和):和为k的子数组,和可被k整除的子数组

【优选算法必刷100题】第029-030题(前缀和):和为k的子数组,和可被k整除的子数组

🔥个人主页:Cx330🌸

❄️个人专栏:《C语言》《LeetCode刷题集》《数据结构-初阶》《C++知识分享》

《优选算法指南-必刷经典100题》《Linux操作系统》:从入门到入魔

🌟心向往之行必能至


🎥Cx330🌸的简介:


目录

前言:

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 n=nums.size(); int sum=0,ret=0; for(auto x:nums) { sum+=x; if(hash.count(sum-k)) ++ret; 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++ 中关于负数的取模运算,结果是「把负数当成正数,取模之后的结果加上一个负号」。 例如:-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;//0这个数的余数 int sum,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; } };

博主手记(字体还请见谅哈):


结尾:

总结:引入同余定理处理负数取模问题,同样采用哈希表优化查询效率,通过维护前缀和哈希表,将时间复杂度优化至O(n),展示了前缀和技巧在子数组统计问题中的高效应用

Read more

华为OD机试双机位C卷:螺旋数字矩阵 (C/C++/Py/Java/Js/Go)

华为OD机试双机位C卷:螺旋数字矩阵 (C/C++/Py/Java/Js/Go)

螺旋数字矩阵 华为OD机试双机位C卷 - 华为OD上机考试2025年双机位C卷 100分题型 华为OD机试双机位C卷真题目录点击查看: 华为OD机试双机位C卷真题题库目录|机考题库 + 算法考点详解 题目描述 疫情期间,小明隔离在家,百无聊赖,在纸上写数字玩。他发明了一种写法: 给出数字个数n和行数m(0 < n ≤ 999,0 < m ≤ 999),从左上角的1开始,按照顺时针螺旋向内写方式,依次写出2,3…n,最终形成一个m行矩阵。 小明对这个矩阵有些要求: * 每行数字的个数一样多 * 列的数量尽可能少 * 填充数字时优先填充外部 * 数字不够时,使用单个*号占位 输入描述 输入一行,两个整数,空格隔开,依次表示n、m 输出描述 符合要求的唯一矩阵 示例1 输入 9 4 输出

【C++:C++11】C++11新特性深度解析:从可变参数模板到Lambda表达式

【C++:C++11】C++11新特性深度解析:从可变参数模板到Lambda表达式

🎬 个人主页:艾莉丝努力练剑 ❄专栏传送门:《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录》 《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬 艾莉丝的简介: 🎬 艾莉丝的C++专栏简介: 文章目录 * C++学习阶段的三个参考文档 * 4 ~> 可变参数模版 * 4.5 emplace系列接口 * 4.5.1 不同容器emplace系列接口展示 * 4.5.2 浅谈emplace系列接口概念 * 4.5.3 emplace系列接口在list.h文件中的使用 * 4.5.4 emplace系列接口在Test.cpp文件中的使用 * 4.

【C++】priority_queue和deque的使用与实现

【C++】priority_queue和deque的使用与实现

priority_queue与deque的使用与模拟实现 ✨前言:在C++ STL中,priority_queue和deque是两个重要的容器适配器,它们分别基于堆和双端队列的概念,为不同的应用场景提供了高效的解决方案。本文将深入探讨它们的使用方法、底层实现原理以及在实际开发中的应用选择。 📖专栏:【C++成长之旅】 目录 * priority_queue与deque的使用与模拟实现 * 一、priority_queue * 1.1 介绍 * 1.2 使用 * 1.3 模拟实现 * 二、deque * 2.1 介绍 * 2.2 缺陷 * 三、STL标准库中对于stack和queue的模拟实现 * 3.1 为什么选择deque作为stack和queue的底层默认容器 * 3.2 stack的模拟实现 * 3.3 queue的模拟实现 一、priority_

c++的多态

c++的多态

1.多态的概念  多态,通俗来说,就是多种形态 多态分为编译时多态(静态多态)和运⾏时多 态(动态多态) 静态多态主要是函数重载和函数模板,它们传不同类型的参数就可以调⽤不同的函数,通过参数不同达到多种形态,之所以叫编译时多态,是因为他们实参传给形参的参数匹配是在 编译时完成的,我们把编译时⼀般归为静态,而运⾏时归为动态 动态多态主要是指:传不同的对象就会完成不同的⾏为,达到多种形态,比如一个动物叫声的行为(函数),传一个猫对象过去就是”喵喵“,传一个蛇对象过去就是”嘶嘶“,传一个狗对象过去就是”旺旺“ 2.多态的定义及其实现 2.1构成多态的条件 多态是⼀个继承关系的下的类对象,去调⽤同⼀函数,产⽣了不同的⾏为 比如学生买火车票,是学生票,普通人买票就是普通票 条件: