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

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

🔥小叶-duck个人主页

❄️个人专栏《Data-Structure-Learning》

《C++入门到进阶&自我学习过程记录》《算法题讲解指南》--从优选到贪心

未择之路,不须回头
已择之路,纵是荆棘遍野,亦作花海遨游


目录

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 count = 0; int sum = 0; for(int i = 0; i < nums.size(); i++) { sum += nums[i]; if(hash[sum - k]) { count += hash[sum - k]; } hash[sum]++; } return count; } };

算法总结及流程解析:

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; int count = 0; int sum = 0; int rem = 0; hash[0] = 1; //这里的0表示i位置前缀和正好被k整除 for(auto i : nums) { sum += i; rem = sum % k; if(rem < 0) //负数 % 正数 -> 负数 —> 需要修正为正数 -> 负数+k { rem += k; } if(hash[rem]) //同余定理:(a - b)/p = k -> (a - b)%p == 0 -> a%p == b%p { count += hash[rem]; } hash[rem]++; } return count; } };

算法总结及流程解析:

结束语

      到此,29.和为k的子数组,30.和可被k整除的子数组 这两道算法题就讲解完了。两道题均采用前缀和+哈希表方法,通过统计前缀和出现的次数来快速计算符合条件的子数组数量。第二题在类似思路基础上结合同余定理,处理了负数取模问题。希望大家能有所收获!

Read more

【干货】HNSW算法详解:从基础到进阶,掌握大模型向量搜索核心技术!

【干货】HNSW算法详解:从基础到进阶,掌握大模型向量搜索核心技术!

简介 本文详细介绍了HNSW算法,一种用于高维空间中最近邻搜索的高效索引方法。文章从基础概念开始,逐步解释了可导航图和NSW算法的工作原理、构建与搜索过程,以及其局限性。随后介绍了跳表数据结构,并详细阐述了HNSW的多层级构建和搜索机制。通过比较HNSW与NSW的搜索效率,展示了HNSW在减少跳数和提高搜索准确性方面的优势,为在大模型应用中实现高效的向量相似性搜索提供了技术基础。 HNSW(Hierarchical Navigable Small World)可能是专为高维空间中的最近邻搜索而设计的最有效、最高效的索引方法之一。其核心思想是构建一个图结构,其中每个节点代表一个数据向量,边根据节点的相似性进行连接。HNSW 以这样一种方式组织图表,通过有效地浏览图表来找到近似的最近邻居,从而促进快速搜索操作。但在我们理解 HNSW 之前,必须先理解NSW(可导航小世界算法),它是 HNSW 算法的基础。 什么是可导航图 如果我们将这些向量表示为图的顶点,则彼此靠近的顶点(即相似度高的向量)应该作为邻居连接。也就是说,即使两个节点没有直接连接,也应该可以通过遍历其他顶点到达它们。

By Ne0inhk
【强化学习】Double DQN(Double Deep Q-Network)算法

【强化学习】Double DQN(Double Deep Q-Network)算法

📢本篇文章是博主强化学习(RL)领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在👉强化学习专栏:        【强化学习】- 【单智能体强化学习】(12)---《Double DQN(Double Deep Q-Network)算法》 Double DQN(Double Deep Q-Network)算法 目录 一、Double DQN算法详解 二、算法背景和提出 2.1 过估计偏差问题 2.2 Double Q-Learning的灵感 2.3 Double DQN的提出 三、Double DQN的核心思想 四、算法流程

By Ne0inhk
看一遍就懂:动态规划详解

看一遍就懂:动态规划详解

目录 前言 什么是动态规划? 核心思想 例子1 — 青蛙跳台阶问题 1. 暴力递归解法(超时示范) 2. 带备忘录的递归(自顶向下) 3. 动态规划(自底向上) 动态规划解题套路总结 经典案例:最长递增子序列(LIS) 1. 穷举分析 2. 状态转移方程 3. 代码实现 总结 前言 刷 LeetCode 的时候,经常会遇到动态规划(DP)类型题目。动态规划既经典又有技巧,大厂面试题里常常出现。很多同学第一次接触时会觉得很抽象,今天我们就来一起剖析动态规划的套路,带你从入门到精通。 什么是动态规划? 动态规划(Dynamic Programming,简称 DP)是一种解决复杂问题的算法设计方法,其核心思想是将原问题拆解成相对简单的子问题,逐个解决并保存子问题的结果,避免重复计算,从而高效地求解问题。 动态规划适合具有以下两个性质的问题:

By Ne0inhk
【递归、搜索与回溯算法必刷42题:专题一】从汉诺塔问题到快速幂

【递归、搜索与回溯算法必刷42题:专题一】从汉诺塔问题到快速幂

🎬 个人主页:艾莉丝努力练剑 ❄专栏传送门:《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录》 《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬 艾莉丝的简介: 🎬艾莉丝的算法专栏简介: 文章目录 * 本文设计专题一算法题链接 * 1 汉诺塔问题 * 题目描述 * 汉诺塔问题(递归解法) * 1. 问题描述 * 2. 递归思想 * 基本情况(递归终止条件) * 递归分解(n ≥ 2) * 3. 递归算法流程(函数设计) * 函数头 * 递归函数流程: * 解题过程 * 算法实现(C++) * 2 合并两个有序链表 * 题目描述 * 解题过程 * 算法实现(

By Ne0inhk