优选算法——前缀和(5):和为 K 的子数组

优选算法——前缀和(5):和为 K 的子数组
示例图

🔥近津薪荼: [个人主页]🎬个人专栏: 《近津薪荼的算法日迹》《Linux操作系统及网络基础知识分享》《c++基础知识详解》《c语言基础知识详解》✨不要物化,矮化,弱化,钝化自己,保持锋芒,不要停止学习这个世界上只有两个人真正在注意着你八岁的你,和八十岁的你,他们此刻正在注视着你,一个希望你 勇敢开始,一个希望你 不留遗憾


1.上期参考代码

classSolution{public: vector<int>productExceptSelf(vector<int>& nums){int n=nums.size(); vector<int>front(n,1);for(int i=1;i<n;i++){ front[i]=front[i-1]*nums[i-1];} vector<int>back(n,1);for(int i=n-2;i>=0;i--){ back[i]=back[i+1]*nums[i+1];} vector<int>ret(n);for(int i=0;i<n;i++){ ret[i]=front[i]*back[i];}return ret;}};

2.本期知识点导图

3.本期要讲解的题目是

和为 K 的子数组

要点:

  • 子数组是数组元素的连续非空排列
  • 注意数组元素有正有负

4.解题

4.1 暴力解法:

暴力枚举,算出所有子数组的和,需嵌套3层循环,时间复杂度O(N3)(前两层枚举子数组左右区间,里层数组求和)

4.2优解

思考

联系我们之前做过双指针,滑动窗口的题,寻找符合条件的子数组,我们这道题目可以使用吗?

使用双指针解决问题是利用双指针的不回退降低遍历数组的时间复杂度 ,其要依赖窗口信息的单调性来实现

本题数组元素包含0和负数,导致求和(窗口信息)不具有单调性了!

我们思考能否由我们自己塑造单调性呢,显然做不到,目前我们塑造单调性,只使用过排序,然而排序并不能解决求和的单调性问题

双指针的思路只能放弃

对于数组求和,我们还接接触过一种算法:前缀和

前缀和

用前缀和,就别管那么多了,直接在数组前n项和的变式上,摸索摸索

如图:我们将数组抽象成一个线条方便画图

画完发现像个嘴唇

上图中,是对于数组中随机的一个符合条件的子数组进行的分析

图中子数组的右区间是 i

我们发现子数组和为k,那么它前边的区间部分的和,必然是sum[ i ]-k

核心思想

那么我们就可以推出,对于数组的前i项,其前缀和数组中存在值为sum[ i ]-k的话,必然存在一个子数组,它的和为k

我们要统计和为k的子数组的个数,即统计i之前的数组的前缀和为sum[i]-k的个数,使用hash表即可,统计完之后,把它累加给ret即可

细节
  • 不可以也没必要一次性把所有的前缀和全部算出来,因为在i之后,有新的元素的加入,可能还会有满足前缀和为sum[i]-k的位置出现,比如i+1的位置为-1,i+2的位置为1。sum[i+2]-k等于sum[i]-k,但是它的位置就不对了,没有对应的和为k的子数组,但是我们统计的标准是统计前缀和为sum[i]-k,hash会把它统计到,属于无效统计。
  • 在前i-1个位置的前缀和中汇总数组的前缀和为sum[i]-k的个数,然后再把sum[i]加入到哈希表中,这是为了防止k=0时的误判,若k=0,先将sum[i]加入到哈希表,不管是否有和为0的子数组,sum[i]必然满足与sum[i]-k相等的条件,这样我们的判断标准就失灵了。
  • 如果sum[i]本身就为k,那么sum[i]-k等于0,那么sum[i]也是满足条件的,但是我们hash只统计前i-1个位置,所以在开始之前,hash[0]的值就应该是1。

代码逻辑:

  • 初始化hash[0]=1,ret

— 进入循环,遍历数组

  • 求i位置的前缀和
  • 汇总符合条件的数组个数
  • 将i位置的前缀和统计到hash

5.下期要讲解的题目是:

和可被 K 整除的子数组

6.嗟食

如果小编写的内容对佬有帮助,还请大佬点点三连加关注哦

在这里插入图片描述


佬的支持就是我前进的最大动力~

期待与佬的再次相遇~

Read more

三种适用于Web版IM(即时通讯)聊天信息的加密算法实现方案

三种适用于Web版IM(即时通讯)聊天信息的加密算法实现方案

文章目录 * **第一部分:引言与核心密码学概念** * **1.1 为什么IM需要端到端加密(E2EE)?** * **1.2 核心密码学概念与工具** * **第二部分:方案一:静态非对称加密(基础方案)** * **2.1 方案概述与流程** * **2.2 前端Vue实现(使用node-forge)** * **1. 安装依赖** * **2. 核心工具类 `crypto.js`** * **3. Vue组件中使用** * **2.3 后端Java实现(Spring Boot)** * **1. 实体类** * **2. Controller层** * **3. WebSocket配置** * **2.4 密钥管理、注册与登录集成** * **1. 用户注册/登录时生成密钥** * **2. 密钥设置页面** * **2.

By Ne0inhk
前端引入的JS加载失败页面功能无法使用?JS加载失败的终极解决方案

前端引入的JS加载失败页面功能无法使用?JS加载失败的终极解决方案

🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Micro麦可乐的博客 🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战 🌺《RabbitMQ》专栏19年编写主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战 🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解 🌛《开源项目》本专栏主要介绍目前热门的开源项目,带大家快速了解并轻松上手使用 🍎 《前端技术》专栏以实战为主介绍日常开发中前端应用的一些功能以及技巧,均附有完整的代码示例 ✨《开发技巧》本专栏包含了各种系统的设计原理以及注意事项,并分享一些日常开发的功能小技巧 💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程 🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整 👍《Spring Security》专栏中我们将逐步深入Spring Security的各个

By Ne0inhk
【LCA DFS 前缀和】P10391 [蓝桥杯 2024 省 A] 零食采购|普及+

【LCA DFS 前缀和】P10391 [蓝桥杯 2024 省 A] 零食采购|普及+

本文涉及知识点 C++算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 C++DFS 倍增算法(multiply)、树上倍增、最近公共祖先(LCA) P10391 [蓝桥杯 2024 省 A] 零食采购 题目描述 小蓝准备去星际旅行,出发前想在本星系采购一些零食,星系内有 n n n 颗星球,由 n − 1 n-1 n−1 条航路连接为连通图,第 i i i 颗星球卖第 c i c_i ci 种零食特产。小蓝想出了 q q

By Ne0inhk
【初阶数据结构与算法】线性表之链表的分类以及双链表的定义与实现

【初阶数据结构与算法】线性表之链表的分类以及双链表的定义与实现

文章目录 * 一、链表的分类 * 二、双链表的实现 * 1.双链表结构的定义 * 2.双链表的初始化和销毁 * 初始化函数1 * 初始化函数2 * 销毁函数 * 3.双链表的打印以及节点的申请 * 打印函数 * 节点的申请 * 4.双链表的头插和尾插 * 头插函数 * 尾插函数 * 5.双链表的查找和判空 * 查找函数 * 判空函数 * 6.双链表的头删和尾删 * 头删函数 * 尾删函数 * 7.双链表指定节点位置的操作 * 删除指定的节点 * 在指定节点前插入数据 * 三、单链表和双链表的简单对比 一、链表的分类 在上一篇中,我们简单了解了单链表,但是我们没有仔细的对链表的分类进行分析,因为我们是第一次接触到链表这种结构,所以我们先简单了解一下单链表,实现一下,现在才能对我们链表的分类有清晰的认知 接下来我们来了解一下链表的具体分类,然后从分类中找出我们上节课实现的单链表,如下: 在上

By Ne0inhk