算法笔记(三)——前缀和算法
算法笔记(三)——前缀和算法
文章目录
- 算法笔记(三)——前缀和算法
- 一维前缀和
- 二维前缀和
- 寻找数组的中心下标
- 除自身以外数组的乘积
- 和为 K 的子数组
- 和可被 K 整除的子数组
- 连续数组
- 矩阵区域和
前缀和算法是一种用空间换时间的算法,他常常用于解决某些题目或者作为某些高级算法的组成部分
一维前缀和
题目链接:DP34 【模板】前缀和
思路
- 通过数组
arr
存储输入的n
个整数,数组dp
存储数组arr
的前缀和 - 使用循环读取数组元素,并计算前缀和
dp
- 进行
q
次查询,每次查询给定一个区间[l, r]
。查询结果为dp[r] - dp[l-1]
,表示数组在区间[l, r]
的和
C++代码
#include<iostream>
using namespace std;int main()
{int n, q;cin >> n >> q;long long arr[100001]={0}, dp[100001]={0};for(int i = 1; i <= n;++i){cin >> arr[i];dp[i] = arr[i] + dp[i-1];}while(q--){int l, r;cin >> l >> r;cout << dp[r] - dp[l-1] << endl;}return 0;
}
二维前缀和
题目:DP35 【模板】二维前缀和
思路
初始化前缀和
- 构造前缀和数组
dp[i][j]
,其含义是从(1,1)到(i,j)
区域的面积; D区域
也是dp[i][j]
存储的值,其面积也等于A+B+C+D
- 初始化前缀和
dp[i][j] = (A+B)+(A+C)+D - A = dp[i-1][j]+dp[i][j-1]+arr[i][j]-dp[i-1][j-1]
使用前缀和计算
D = A+B+C+D-(A+B)-(A+C)+A
D = dp[i][j]-dp[i][j-1]-dp[i-1][j]+dp[i-1][j-1]
C++代码
#include <iostream>
using namespace std;int arr[1100][1100];
long long dp[1100][1100];
int n, m, q, x1, x2, y1, y2;int main()
{cin >> n >> m >> q;for(int i = 1; i <=n; i++){for(int j = 1; j <= m; j++){cin >> arr[i][j];dp[i][j] = dp[i-1][j] + dp[i][j-1] + arr[i][j] - dp[i-1][j-1]; }}while(q--){cin >> x1 >> y1 >> x2 >> y2;cout << dp[x2][y2] - dp[x1-1][y2] - dp[x2][y1-1] + dp[x1-1][y1-1] << endl;}return 0;
}
寻找数组的中心下标
题目:寻找数组的中心下标
思路
- 初始化
f
表示前缀和,g
表示后缀和 f[i]
表示[0,i-1]
所有元素的和,f[i] = f[i-1] + nums[i-1]
;g[i]
表示[i+1,n-1]
所有元素的和,g[i] = g[i+1] + nums[i+1]
;- 遍历数组
nums
,找到一个索引,使得f[i]
(左侧元素的和)等于l[i]
(右侧元素的和)
C++代码
class Solution {
public:int pivotIndex(vector<int>& nums) {int n = nums.size();vector<int> f(n), g(n);for (int i = 1; i < n; i++)f[i] = f[i - 1] + nums[i - 1];for (int i = n - 2; i >= 0; i--)g[i] = g[i + 1] + nums[i + 1];for (int i = 0; i < n; i++)if (f[i] == g[i])return i;return -1;}
};
除自身以外数组的乘积
题目:除自身以外数组的乘积
思路
- 初始化
f
表示前缀积,g
表示后缀积 f[i]
表示[0,i-1]
所有元素的积,f[i] = f[i - 1] * nums[i - 1]
;g[i]
表示[i+1,n-1]
所有元素的积,g[i] = g[i+1] * nums[i+1]
;- 遍历数组
nums
,计算res[i]
的值
C++代码
class Solution
{
public:vector<int> productExceptSelf(vector<int>& nums) {int n = nums.size();vector<int> f(n + 1);vector<int> g(n + 1);vector<int> res(n);f[0] = 1, g[n - 1] = 1; for(int i = 1; i < n; i++)f[i] = f[i - 1] * nums[i - 1];for(int i = n - 2; i >= 0; i--)g[i] = g[i + 1] * nums[i + 1];for(int i = 0; i < n; i++)res[i] = f[i] * g[i];return res; }
};
和为 K 的子数组
题目:和为 K 的子数组
思路
将问题转化为寻找和为k的子数组
,
而不是直接在数组中寻找和为k的连续元素,
这样就可以使问题在一次遍历中解决
具体来说就是:对于每个前缀和,都检查是否存在一个早先的前缀和,使得它们的差等于k。如果存在,就找到了一个和为k的子数组
- 初始化一个哈希表
hash
,其中hash[0]
表示和为 0 的子数组的个数,初始化为 1 - 两个变量
sum
和ret
,其中 sum 表示当前累积的和,ret 表示满足条件的子数组的个数 - 遍历数组
nums
,累积和并更新哈希表
对于每个元素x
,更新sum += x
检查是否存在之前的累积和sum - k
在哈希表中,如果存在,则累加hash[sum - k]
到ret
。更新哈希表中的当前累积和sum
的计数
C++代码
class Solution
{
public:int subarraySum(vector<int>& nums, int k) {// K:前缀和// V:前缀和出现的次数unordered_map<int, int> hash;int sum = 0, ans = 0;// 初始化时为空区间,则前缀和为0,出现的次数为1hash[0] = 1;for(int num : nums) {sum += num; ans += hash[sum - k]; // 要么为0,要么为sum - k出现的次数hash[sum]++;}return ans;}
};
和可被 K 整除的子数组
题目:和可被 K 整除的子数组
补充
- 同余定理
若(a-b) % p = k......0,则a % p = b % p
- C++、Java中
负数%正数
等于负数
修正a % p + p
为了a>0或a<0
统一后(a % p + p) % p
思路
和上题基本相同,转化为在[0, i - 1]
中,找到有多少个前缀和的余数等于(sum % k + k) % k
- 在
for(auto x : nums)
的循环中,遍历数组nums
。对于每个元素x
sum += x
; 累加当前位置的元素,得到当前位置的前缀和。int r = (sum % k + k) % k
if(hash.count(r)) ret += hash[r]
; 检查之前是否存在相同的余数r
,如果存在,则将哈希表中对应的次数累加到结果ret
中。hash[r]++
; 更新哈希表,将当前余数 r 的次数加一
C++代码
class Solution
{
public:int subarraysDivByK(vector<int>& nums, int k) {unordered_map<int, int> hash;hash[0] = 1; // 初始时,前缀和为 0 的余数的个数为 1 int sum = 0;int ret = 0;for(auto x : nums){sum += x; // 当前位置前缀和int r = (sum % k + k) % k;if(hash.count(r)) // 检查之前是否存在相同的余数 r,如果存在ret += hash[r]; hash[r]++; // 更新哈希表,将当前余数 r 的次数加一}return ret;}
};
连续数组
题目:连续数组
思路
- 将 0 看作 -1,问题就转换成在数组中,找出最长的子数组使其和为0
unordered_map<int, int> hash
表示创建一个哈希表,用于存储前缀和以及对应的出现位置- 遍历数组
nums
对于每个元素nums[i]
,如果nums[i] 是 0
,则令sum += -1
;如果是1
,则令sum += 1
。这样sum
就表示当前位置的前缀和; - 判断哈希表中是否存在当前前缀和
sum
。如果存在,说明从上次该前缀和出现的位置到当前位置的子数组的和为零,更新最长长度ret
。 - 如果哈希表中不存在当前前缀和
sum
,则将当前前缀和和对应的位置存入哈希表中
C++代码
class Solution
{
public:int findMaxLength(vector<int>& nums) {unordered_map<int,int> hash;hash[0] = -1;int ret = 0;int sum = 0;for(int i = 0; i < nums.size(); ++i){sum += (nums[i] == 1 ? 1 : -1);if(hash.count(sum)) ret = max(ret, i - hash[sum]);else hash[sum]=i;}return ret;}
};
矩阵区域和
题目:矩阵区域和
思路
二维前缀和问题,但是需要处理好边界问题
int m=mat.size(), n=mat[0].size()
获取矩阵的行数和列数vector<vector<int>> dp(m+1,vector<int>(n+1))
创建二维前缀和数组dp
dp[i][j]
表示矩阵左上角(0,0)
到(i-1,j-1)
的元素和,计算前缀和数组dp
- 对于每个位置
(i,j)
,计算块的左上角和右下角的坐标,确保不超过矩阵边界
C++代码
class Solution
{
public:vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {int m = mat.size(), n = mat[0].size();vector<vector<int>> dp(m + 1, vector<int>(n + 1));for(int i = 1; i <=m; i++)for(int j = 1; j <= n; j++)dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + mat[i - 1][j - 1] - dp[i - 1][j - 1];vector<vector<int>> ret(m,vector<int>(n));for(int i = 0; i < m; i++)for(int j = 0; j < n; j++){int x1 = max(0, i - k) + 1, y1 = max(0, j - k) + 1;int x2 = min(m - 1, i + k) + 1, y2 = min(n - 1, j + k) + 1;ret[i][j] = dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1];}return ret;}
};
相关文章:
算法笔记(三)——前缀和算法
算法笔记(三)——前缀和算法 文章目录 算法笔记(三)——前缀和算法一维前缀和二维前缀和寻找数组的中心下标除自身以外数组的乘积和为 K 的子数组和可被 K 整除的子数组连续数组矩阵区域和 前缀和算法是一种用空间换时间的算法&am…...
Nginx技术深度解析与实战应用
Nginx技术深度解析与实战应用 Nginx是一款轻量级、高性能的Web服务器、反向代理服务器及电子邮件(IMAP/POP3)代理服务器,由俄罗斯的程序设计师Igor Sysoev开发。Nginx以其内存占用少、启动迅速、高并发能力强等特性,在互联网项目…...
Maven Surefire Plugin
Maven Surefire Plugin 最新版本新特性详解 Maven Surefire Plugin 是用于运行单元测试和集成测试的重要工具,支持 JUnit、TestNG 等测试框架。插件的新版本引入了许多新特性和配置选项,这些功能提升了测试执行的性能、灵活性和并发能力。在本节中&…...
八、跳跃、闪避
一、人物跳跃功能 1、动画 设置一个bool值 条件设置为true 2、逻辑 实现跳跃,一定有IsGround;判断是否为地面,进行跳跃功能 写一个跳跃和一个条约结束方法 跳跃设置为false,结束设置为true 3、代码 public void Jump() {if…...
使用辅助分类器 GAN 进行条件图像合成
Conditional Image Synthesis with Auxiliary Classifier GANs Conditional Image Synthesis with Auxiliary Classifier GANs(简称AC-GANs)是一种用于改善生成对抗网络(GANs)进行图像合成的方法。在AC-GANs中,判别器…...
C#中的static关键字:静态成员与单例模式的实现
在C#中,static 关键字是一个非常重要的概念,它用于声明静态成员,这些成员属于类本身,而不是类的任何特定实例。使用 static 关键字可以定义静态类、静态字段、静态属性、静态方法等。此外,理解静态成员也对于实现如单例…...
【优选算法】(第八篇)
目录 串联所有单词的⼦串(hard) 题目解析 讲解算法原理 编写代码 最⼩覆盖⼦串(hard) 题目解析 讲解算法原理 编写代码 串联所有单词的⼦串(hard) 题目解析 1.题目链接:. - 力扣&#…...
告别PPT熬夜!Kimi+AIPPT一键生成PPT,效率upup!
Kimi AiPPT 一键生成PPT 还在为做PPT熬夜加班吗?还在为PPT排版抓狂吗?现在,有一个好消息要告诉所有“打工人”!Kimi和AIPPT强强联手,推出了一键生成PPT功能,让你告别PPT制作的痛苦! 以前做…...
大语言模型在构建UNSPSC 分类数据中的应用
UNSPSC 是联合国标准产品和服务代码。UNSPSC由联合国开发计划署(UNDP)和Dun & Bradstreet公司(D & B)于1998年联合制定,自2003年以来一直由GS1 US管理。GS1 US 将在 2024 年底前将 UNSPSC 的管理权移交给 UNDP…...
C++初阶:STL详解(十)——priority_queue的介绍,使用以及模拟实现
✨✨小新课堂开课了,欢迎欢迎~✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:C:由浅入深篇 小新的主页:编程版小新-CSDN博客 一.priority_queue的介绍 优先级队列被实现…...
Qt | Linux+QFileSystemWatcher文件夹和文件监视(例如监视U盘挂载目录)
点击上方"蓝字"关注我们 01、QFileSystemWatcher >>> QFileSystemWatcher 是 Qt 提供的一个类,用于监视文件和目录的变化。它允许应用程序监控一个或多个文件和目录,并在这些文件或目录内容发生变化时收到通知。这使得 Qt 应用程序能够动态响应文件系统的…...
【Linux进程间通信】Linux匿名管道详解:构建进程间通信的隐形桥梁
📝个人主页🌹:Eternity._ ⏩收录专栏⏪:Linux “ 登神长阶 ” 🌹🌹期待您的关注 🌹🌹 ❀Linux进程间通信 📒1. 进程间通信介绍📚2. 什么是管道📜3…...
【力扣 | SQL题 | 每日三题】力扣1148, 1327, 1211, 1174
1. 力扣1148:文章浏览1 1.1 题目: Views 表: ------------------------ | Column Name | Type | ------------------------ | article_id | int | | author_id | int | | viewer_id | int | | view_date …...
【鸿蒙开发】详解GridRowSizeOption的尺寸属性
文章目录 1. 尺寸属性的含义2. 为什么要有这几个属性3. 具体作用4. 如何使用总结 在鸿蒙(HarmonyOS)开发中,布局的灵活性和适应性对于构建高质量的应用至关重要。 GridRowSizeOption是鸿蒙开发框架提供的一个布局属性,用于定义网…...
Sping源码:三级缓存
目录 一、概念1、三级缓存的作用2、循环依赖的含义 二、代码1、代码下载2、文件功能介绍3、源码分析3.1、找到获取A对象的位置,打断点进行debug操作3.2、一步步找到在A对象中注入B对象的位置3.3、一步步找到B对象注入A对象的位置3.4、往下找到通过三级缓存解决循环依…...
latex有哪些颜色中文叫什么,Python绘制出来
latex有哪些颜色中文叫什么,Python绘制出来 为了展示xcolor包预定义的颜色及其对应的中文名称,并使用Python打印出来,我们可以先列出常见的预定义颜色名称,然后将它们翻译成中文,并最后用Python打印出来。 步骤 列出…...
C语言进程
什么是进程 什么是程序 一组可以被计算机直接识别的 有序 指令 的集合。 通俗讲:C语言编译后生成的可执行文件就是一个程序。 那么程序是静态还是动态的? 程序是可以被存储在磁盘上的,所以程序是静态的。 那什么是进程 进程是程序的执行过…...
C#基础(4)封装——成员方法
前言 我们在上一节学习了关于类的成员变量的使用,甚至也看到了相应的成员方法,我们可以将二者理解为类里面的变量和函数。 如果我这样说你肯定就能很快理解成员方法是什么作用了。 C#中设计成员方法的目的是为了将相关的功能代码组织在一起࿰…...
springbot,JWT令牌的使用。实现http请求拦截校验。
JWT 由三部分组成,用点(.)分隔 Header(头部) Payload(负载)Signature(签名) 一、原理 Jwt原理其实很简单,在后端首先要有个拦截器,他会拦截所有http请求&…...
【SQL】DDL语句
文章目录 1.SQL通用语法2.SQL的分类3.DDL3.1数据库操作3.2 表操作3.2.1 表操作--数据类型3.2.2 表操作--修改3.2.3 表操作--删除 SQL 全称 Structured Query Language,结构化查询语言。操作关系型数据库的编程语言,定义了一套操作关系型数据库统一标准 。…...
【分页】Spring Boot 列表分页 + javaScript前台展示
后端: 准备好查询实体与分页实体 1、分页工具实体 package com.ruoyi.dms.config;import com.alibaba.nacos.api.model.v2.Result; import lombok.Data;import java.io.Serializable; import java.util.List;/*** author 宁兴星* description: 列表返回结果集*/ …...
「安装」 Windows下安装CUDA和Pytorch
「安装」 Windows下安装CUDA和Pytorch 文章目录 「安装」 Windows下安装CUDA和PytorchMac、Linux、云端Windows安装CUDA安装miniconda安装PyTorch测试总结 其他 Mac、Linux、云端 Mac、Linux、云端安装Miniconda和Pytorch的方法参考其他资料。 Windows 下面进行Windows下安装…...
c语言基础作业
选择题 1.1、以下选项中,不能作为合法常量的是 __________ A)1.234e04 B)1.234e0.4C)1.234e4 D)1.234e0 1.2、以下定义变量并初始化错误的是_____________。 A) char c1 ‘H’ ; B) char c1 9…...
uniapp view增加删除线
推荐学习文档 golang应用级os框架,欢迎stargolang应用级os框架使用案例,欢迎star案例:基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识,这里有免费的golang学习笔…...
[Day 83] 區塊鏈與人工智能的聯動應用:理論、技術與實踐
區塊鏈在物聯網中的應用 區塊鏈技術與物聯網(IoT)結合,為許多領域提供了強大的解決方案。傳統的IoT架構常面臨數據隱私和安全問題,而區塊鏈的去中心化和加密技術則能有效增強IoT系統的安全性、透明性和效率。本文將探討區塊鏈如何…...
Java ReentrantLock
目录 1 互斥性 2 公平性 3 可重入性 4 获取和释放锁 5 尝试获取锁 6 可中断的锁定 7 条件变量 8 性能 9 使用场景 ReentrantLock 是 Java 提供的一种可重入的互斥锁,位于 java.util.concurrent.locks 包中,它实现了 Lock 接口。这个锁提供了与内…...
【Linux系统编程】第二十六弹---彻底掌握文件I/O:C/C++文件接口与Linux系统调用实践
✨个人主页: 熬夜学编程的小林 💗系列专栏: 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】 目录 1、回顾C语言文件接口 1.1、以写的方式打开文件 1.2、以追加的方式打开文件 2、初步理解文件 2.1、C文件接口 3、进一步理…...
数据分析-29-基于pandas的窗口操作和对JSON格式数据的处理
文章目录 1 窗口操作1.1 滑动窗口思想1.2 函数df.rolling2 JSON格式数据2.1 处理简单JSON对象和JSON列表2.1.1 处理简单的JSON结构2.1.2 处理空字段2.1.3 获取部分字段2.2 处理多级json2.2.1 展开所有级别(默认)2.2.2 自定义展开层级2.3 处理嵌套列表JSON3 参考附录1 窗口操作 …...
Ubuntu-WSL2一键设置代理操作
现状: Window11中拥有自己的代理软件 ,可以科学上网已在WSL2中安装Ubuntu22.04 需求: Ubuntu-WSL2实现科学上网 实现: 参考:为 WSL2 一键设置代理 Linux 子系统中的网关指向的是 Windows,DNS 服务器指…...
ubuntu命令行连接wifi
在Ubuntu上,你可以通过命令行连接到Wi-Fi网络。以下是详细步骤,主要使用 nmcli 和 nmtui 命令。 方法 1:使用 nmcli nmcli 是 NetworkManager 的命令行界面,用于管理网络连接。以下是使用 nmcli 连接到 Wi-Fi 网络的步骤&#x…...
盐城有没有做网站吗/seo是免费的吗
作为程序员,相较于其它行业的人们面试的时候有个很痛苦的问题就是,很注重基础的考察,特别是数据结构基础的考察,不管你经验多么的丰富,特别是职业生涯中后期侧重于架构或者更上层的开发,你往往会忽略了基础…...
怎么查看网站是哪个公司做的/技能培训班有哪些
有网友留言说不小心打开了好多窗口,一个一个关闭真是要崩溃了,有没有一种简单的方法能有一键关闭所有视窗呢?今天就给大家介绍这种一键关闭视窗的方法。 今天就给大家分享一个小技巧,在这个情况下非常好用,可以快速关…...
大丰做网站价格/电商平台如何推广运营
一、简介 JAXB(Java API for XML Binding)是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到 XML实例文档。 Jaxb 2.0是JDK 1.6的…...
wordpress zw/网络营销平台名词解释
如何将训练好的网络进行保存以便以后使用, 进行后续的研究呢? 首先,定义一个简单的LSTM模型: from keras.models import Sequential from keras.layers import LSTM, Dense model Sequential() model.add(LSTM(4,input_shape(1,8))) model.add(Dense(1)) 整体保存模型及参…...
邹平市建设局官方网站/网站推广的方式有哪些
CountDownLatch与CyclicBarrier的使用与区别 CountDownLatch的介绍和使用: 一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。 用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法&…...
个人可以做电商网站吗/关于华大18年专注seo服务网站制作应用开发
单机Docker部署应用Kraft模式的Kafka集群1 Docker镜像准备1.1 下载Kafka1.2 配置容器1.3 修改kafka配置2 部署Kafka集群2.1 启动节点容器2.2 生成一个 Cluster ID2.3 格式化存储目录2.4 启动kafka服务3 知识3.1 控制器服务器3.2 进程角色3.3 仲裁投票者3.4 Kafka存储工具3.5 缺…...