LeetCode-刷题记录-前缀和合集(本篇blog会持续更新哦~)
一、前缀和(Prefix Sum)算法概述
前缀和算法通过预先计算数组的累加和,可以在常数时间内回答多个区间和相关的查询问题,是解决子数组和问题中的重要工具。

它的基本思想是通过预先计算和存储数组的前缀和,可以在 O(1) 的时间复杂度内计算任意子数组的和。

- 定义:
- 对于数组
nums,其前缀和prefix[i]定义为从数组起始位置到第i个元素的累加和。
- 对于数组

- 具体公式:
prefix[i] = nums[0] + nums[1] + ... + nums[i]。
- 计算方法:
- 首先,创建一个额外的数组或哈希表,用来存储每个位置的前缀和。
- 通过一次遍历数组,依次计算并填充这个数组或哈希表。

- 应用:
- 快速计算子数组和:通过前缀和,可以快速计算任意子数组的和。例如,子数组
nums[l...r]的和可以通过prefix[r] - prefix[l-1]来计算,其中l和r分别是子数组的左右边界。
- 快速计算子数组和:通过前缀和,可以快速计算任意子数组的和。例如,子数组

- 解决相关问题:例如,最大子数组和、和为特定值的子数组个数等问题,都可以通过前缀和算法高效解决。

二、前缀和习题合集
1. LeetCode 930 和相同的二元子数组

- 思路:
假设原数组的前缀和数组为 sum,且子数组 (i,j] 的区间和为 goal,那么 sum[j]−sum[i]=goal。因此我们可以枚举 j ,每次查询满足该等式的 i 的数量。
用哈希表记录每一种前缀和出现的次数,假设我们当前枚举到元素 nums[j],我们只需要查询哈希表中元素 sum[j]−goal 的数量即可,这些元素的数量即对应了以当前 j 值为右边界的满足条件的子数组的数量。
-
pre[j] - pre[i]= goal —> pre[i] = pre[j] - goal
-
如果存在前缀和为 pre[j] - goal(也就是pre[i])
-
说明从某个位置 j 到当前位置 i 的子数组和为 goal
最后这些元素的总数量即为所有和为 goal 的子数组数量。
- 代码:
class Solution {public int numSubarraysWithSum(int[] nums, int goal) {int n = nums.length; // 数组的长度Map<Integer,Integer> map = new HashMap<>(); // 使用哈希表来记录前缀和的出现次数int pre_J = 0; // 初始前缀和为0int ans = 0; // 计数器,用来记录符合条件的子数组个数for (int i = 0; i < n; i++) {map.put(preJ, map.getOrDefault(pre_J, 0) + 1); // 更新前缀和为 preJ 的出现次数pre_J += nums[i]; // 计算当前位置的前缀和//pre[j] - pre[i]= goal //pre[i] = pre[j] - goal// 计算满足条件的子数组个数// 如果存在前缀和为 pre[j] - goal(也就是pre[i])//说明从某个位置 j 到当前位置 i 的子数组和为 goalans += map.getOrDefault(pre_J - goal, 0);}return ans; // 返回符合条件的子数组个数}
}
2. LeetCode 560 和为K的子数组

-
这里咋一看好像是可以用滑动窗口哈 ,但是发现数据里有负数。因为nums[i]可以小于0,也就是说右指针j向后移1位不能保证区间会增大,左指针i向后移1位也不能保证区间和会减小。
-
思路 : 同上一题类似
前缀和 + 哈希
class Solution {public static int subarraySum(int[] nums, int k) {int n = nums.length; // 获取数组长度Map<Integer,Integer> map = new HashMap<>(); // 创建哈希表,用于存储前缀和及其出现次数int sum = 0; // 初始化前缀和为0int ans = 0; // 初始化结果为0map.put(sum,1); // 将初始的前缀和0放入哈希表,并设其出现次数为1// 遍历数组for(int num : nums){sum += num; // 计算当前位置的前缀和// 如果哈希表中存在前缀和为sum-k的项,则说明存在和为k的子数组 sum - (sum-k) = kif(map.containsKey(sum - k)){ans += map.get(sum - k); // 更新结果,累加前缀和为sum-k的子数组数量}map.put(sum, map.getOrDefault(sum, 0) + 1); // 更新哈希表,将当前前缀和放入,并更新出现次数}return ans; // 返回结果}
}
-
初始时,将前缀和为 0 放入哈希表
map中,表示在初始状态下存在一个前缀和为 0 的情况,出现次数为 1。 -
如果
map中存在sum - k,则说明从之前的某个位置到当前位置的子数组的和为k。这是因为sum - (sum - k) = k。 -
如果存在这样的前缀和,则将该前缀和的出现次数累加到
ans中。
3. LeetCode 523 连续的子数组和


- 这里要用到数学知识——同余定理

-
前缀和的定义: 设
preSum[i]表示nums数组从 0 到 i 的元素之和。- 如果存在一个子数组
nums[j..i](j < i),其和是k的倍数,则preSum[i] - preSum[j-1]必须是k的倍数。
- 如果存在一个子数组
-
利用余数的性质(同余定理):
- 如果
preSum[i]和preSum[j-1]对k取余得到相同的结果,即(preSum[i] - preSum[j-1]) % k == 0,则存在这样的子数组。 a%k = b%k,则(a-b)%k =0满足条件
- 如果

- 使用哈希表记录余数: 使用哈希表来记录每个余数第一次出现的位置。
class Solution {public boolean checkSubarraySum(int[] nums, int k) {int n = nums.length;int[] pre = new int[n + 1];for (int i = 1; i <= n; i++) {pre[i] = pre[i - 1] + nums[i - 1]; // 计算前缀和}Set<Integer> set = new HashSet<>();for (int i = 2; i <= n; i++) {set.add(pre[i - 2] % k); // 将前缀和前两项的同余结果加入集合if (set.contains(pre[i] % k)) return true; // 如果当前前缀和对k取模的结果在集合中已经存在,说明找到了符合条件的子数组}return false; // 如果遍历完没有找到符合条件的子数组,返回false}
}
4. LeetCode 724 寻找数组的中心下标

- 前缀和思想
法一:
class Solution {public static int pivotIndex(int[] nums) {int n = nums.length;int[] sumLeft = new int[n]; // 用于存储每个索引位置左侧元素之和int[] sumRight = new int[n]; // 用于存储每个索引位置右侧元素之和sumLeft[0] = 0; // 初始化左侧和数组的第一个元素为0(因为第一个元素左侧没有元素)sumRight[n - 1] = 0; // 初始化右侧和数组的最后一个元素为0(因为最后一个元素右侧没有元素)int sum1 = 0; // 用于计算累积的左侧和int sum2 = 0; // 用于计算累积的右侧和// 计算每个索引位置左侧的累积和for (int i = 0; i < n; i++) {sum1 += nums[i];sumLeft[i] = sum1;}// 计算每个索引位置右侧的累积和for (int i = n - 1; i >= 0; i--) {sum2 += nums[i];sumRight[i] = sum2;}// 遍历数组,找到第一个满足左侧和等于右侧和的索引位置for (int i = 0; i < n; i++) {if (sumLeft[i] == sumRight[i]) {return i;}}// 如果没有找到满足条件的索引,返回-1return -1;}
}
法二:
class Solution {public static int pivotIndex(int[] nums) {int totalSum = 0; // 计算整个数组的和for (int num : nums) {totalSum += num;}int leftSum = 0; // 左侧和的初始值为0for (int i = 0; i < nums.length; i++) {int rightSum = totalSum - leftSum - nums[i]; // 右侧和等于总和减去左侧和和当前数字if (leftSum == rightSum) {return i; // 如果左右两侧和相等,则返回当前索引作为轴心索引}leftSum += nums[i]; // 更新左侧和,将当前数字累加到左侧和中}return -1; // 如果遍历完整个数组都没有找到轴心索引,则返回-1表示不存在}
}
5. LeetCode 238 除自身以外数组的乘积

- 思路 :前缀积 + 后缀积 (左右乘积列表)
我们不必将所有数字的乘积除以给定索引处的数字得到相应的答案,而是利用索引左侧所有数字的乘积和右侧所有数字的乘积(即前缀与后缀)相乘得到答案。
注意这里有一个细节就是要除了自己,所以在累乘的时候,要在当前位置保存 左侧 或者 右侧 (不包含自己)。
前积乘后积,先存后乘避开自己
class Solution {public int[] productExceptSelf(int[] nums) {int n= nums.length;// L 和 R 分别表示左右两侧的乘积列表int[] L = new int[n];int[] R = new int[n];int[] answer = new int[n];// L[i] 为索引 i 左侧所有元素的乘积// 对于索引为 '0' 的元素,因为左侧没有元素,所以 L[0] = 1L[0] = 1;for (int i = 1; i < n; i++) {L[i] = nums[i - 1] * L[i - 1];}// R[i] 为索引 i 右侧所有元素的乘积// 对于索引为 'n-1' 的元素,因为右侧没有元素,所以 R[length-1] = 1R[n- 1] = 1;for (int i = n- 2; i >= 0; i--) {R[i] = nums[i + 1] * R[i + 1];}// 对于索引 i,除 nums[i] 之外其余各元素的乘积就是左侧所有元素的乘积乘以右侧所有元素的乘积for (int i = 0; i < n; i++) {answer[i] = L[i] * R[i];}return answer;}
}
class Solution {public int[] productExceptSelf(int[] nums) {int length = nums.length;int[] answer = new int[length];// answer[i] 表示索引 i 左侧所有元素的乘积// 因为索引为 '0' 的元素左侧没有元素, 所以 answer[0] = 1answer[0] = 1;for (int i = 1; i < length; i++) {answer[i] = nums[i - 1] * answer[i - 1];}// R 为右侧所有元素的乘积// 刚开始右边没有元素,所以 R = 1int R = 1;for (int i = length - 1; i >= 0; i--) {// 对于索引 i,左边的乘积为 answer[i],右边的乘积为 Ranswer[i] = answer[i] * R;// R 需要包含右边所有的乘积,所以计算下一个结果时需要将当前值乘到 R 上R *= nums[i];}return answer;}
}
更新于:

本篇blog会持续更新哦~
相关文章:
LeetCode-刷题记录-前缀和合集(本篇blog会持续更新哦~)
一、前缀和(Prefix Sum)算法概述 前缀和算法通过预先计算数组的累加和,可以在常数时间内回答多个区间和相关的查询问题,是解决子数组和问题中的重要工具。 它的基本思想是通过预先计算和存储数组的前缀和,可以在 O(1)…...
【中项第三版】系统集成项目管理工程师 | 第 4 章 信息系统架构③ | 4.6
前言 第4章对应的内容选择题和案例分析都会进行考查,这一章节属于技术相关的内容,学习要以教材为准。本章分值预计在4-5分。 目录 4.6 网络架构 4.6.1 基本原则 4.6.2 局域网架构 4.6.3 广域网架构 4.6.4 移动通信网架构 4.6.5 软件定义网络 4.6…...
知识图谱入门笔记
自学参考: 视频:斯坦福CS520 | 知识图谱 最全知识图谱综述 详解知识图谱的构建全流程 知识图谱构建(概念,工具,实例调研) 一、基本概念 知识图谱(Knowledge graph):由结…...
常见的气体流量计有哪些?
1.气体涡轮流量计 适用场合:流量变化小,脉动流频率小,中低压洁净天然气优点 1.精度高,重复性好 2.测量范围广,压损小,安装维修方便 3.具有较高的抗电磁干扰和抗震动能力缺点:分辨率低ÿ…...
AI推介-大语言模型LLMs论文速览(arXiv方向):2024.07.01-2024.07.05
文章目录~ 1.LLM Internal States Reveal Hallucination Risk Faced With a Query2.Fine-Tuning with Divergent Chains of Thought Boosts Reasoning Through Self-Correction in Language Models3.Investigating Decoder-only Large Language Models for Speech-t…...
Android IP地址、子网掩码、默认网关、首选DNS服务器、备用DNS服务器校验
Android IP地址、子网掩码、默认网关、首选DNS服务器、备用DNS服务器校验 public String isIP(String ip) {String regex = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]?\\d)){3}";Pattern p = Pattern.compile(regex)...
铁威马NAS教程丨为什么修复文件系统、为卷扩容、增加及删除 SSD 缓存等操作失败?
适用机型: 所有 TNAS 型号 适用版本: 所有 TOS 版本 问题现象: 在尝试修复文件系统、为卷扩容、增加或删除 SSD 缓存时(TOS 5),可能因卷被其他进程占用而操作失败。 解决方法: 为了成功执行上述操作,您…...
【深度学习】第3章——回归模型与求解分析
一、回归分析 1.定义 分析自变量与因变量之间定量的因果关系,根据已有的数据拟合出变量之间的关系。 2.回归和分类的区别和联系 3.线性模型 4.非线性模型 5.线性回归※ 面对回归问题,通常分三步解决 第一步:选定使用的model,…...
Maven的基本使用
引入依赖 1.引入Maven仓库存在的依赖,直接引入,刷新Maven <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.2.12.RELEASE</version> </dependency…...
【笔记】finalshell中使用nano编辑器GNU
ctrl O 保存 enter 确定 ctrl X 退出 nano编辑 能不用就不用吧 因为我真用不习惯 nano编辑的文件也可以用vim编辑的...
markdown文件转pdf
步骤:md转html转pdf pom引入 <!--markdown 转pdf--><dependency><groupId>com.vladsch.flexmark</groupId><artifactId>flexmark-all</artifactId><version>0.64.8</version></dependency><dependency&g…...
课设:二手车交易管理系统(Java+MySQL)
简易数据库课程设计~分享 技术栈 本项目使用以下技术栈构建: Java: 作为主要编程语言,负责业务逻辑的实现。MySQL: 用于数据存储,管理用户、车辆和订单信息。JDBC: 用于Java与MySQL数据库之间的连接和操作。Swing GUI: 提供用户图形界面&am…...
vue3实现无缝滚动 列表滚动 vue3-seamlessscroll
vue3框架内使用无缝滚动,使用一个插件比较合适(gitee地址): vue3-seamless-scroll: Vue3.0 无缝滚动组件 具体更多配置请看: 组件配置 | vue3-scroll-seamless 1. 安装: npm install vue3-seamless-sc…...
Python酷库之旅-第三方库Pandas(012)
目录 一、用法精讲 28、pandas.HDFStore.keys函数 28-1、语法 28-2、参数 28-3、功能 28-4、返回值 28-5、说明 28-6、用法 28-6-1、数据准备 28-6-2、代码示例 28-6-3、结果输出 29、pandas.HDFStore.groups函数 29-1、语法 29-2、参数 29-3、功能 29-4、返回…...
SpringCloud集成nacos之jasypt配置中心的密码加密的自动解密
目录 1.引入相关的依赖 2.nacos的yaml的相关配置,配置密码和相关算法 3.配置数据源连接 3.1 数据库连接配置 4.连接数据库配置类详解(DataSourceConfig)。 5.完整的配置类代码如下 1.引入相关的依赖 <dependency><groupId>…...
Python 中将字典内容保存到 Excel 文件使用详解
概要 在数据处理和分析的过程中,经常需要将字典等数据结构保存到Excel文件中,以便于数据的存储、共享和进一步分析。Python提供了丰富的库来实现这一功能,其中最常用的是pandas和openpyxl。本文将详细介绍如何使用这些库将字典内容保存到Excel文件中,并包含具体的示例代码…...
libaom 编码器 aomenc 使用文档介绍
使用方法:./aomenc <选项> -o 目标文件名 源文件名 使用 --help 查看完整的选项列表。 选项: --help 显示使用选项并退出-c <参数>, --cfg<参数> 使用配置文件-D, --debug 调试模式(使输出确定性)-o <参数&g…...
速盾:cdn 缓存图片
现如今,互联网已经成为我们日常生活中不可或缺的一部分。在我们使用互联网时,经常会遇到图片加载缓慢、文章打开慢等问题。为了解决这些问题,CDN(内容分发网络)应运而生。CDN 是一种通过将数据缓存在世界各地的服务器上…...
移动应用开发课设——原神小助手文档(2)
2023年末,做的移动应用开发课设,分还算高,项目地址:有帮助的话,点个赞和星呗~ GitHub - blhqwjs/-GenShin_imp: 2023年移动应用开发课设 本文按照毕业论文要求来写,希望对大家有所帮助。 接上文:…...
智能聊天机器人:使用PyTorch构建多轮对话系统
使用PyTorch构建多轮对话系统的示例代码。这个示例项目包括一个简单的Seq2Seq模型用于对话生成,并使用GRU作为RNN的变体。以下是代码的主要部分,包括数据预处理、模型定义和训练循环。 数据预处理 首先,准备数据并进行预处理。这部分代码假…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
省略号和可变参数模板
本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
