【算法】基础算法004之前缀和

👀樊梓慕:个人主页

 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》《Linux》《算法》

🌝每一个不曾起舞的日子,都是对生命的辜负


前言

本篇文章为大家带来前缀和算法,前缀和算法可以以O(1)的时间复杂度快速求出某一段连续区间的和,这个连续区域既可以是一维的也可以是二维的。


欢迎大家📂收藏📂以便未来做题时可以快速找到思路,巧妙的方法可以事半功倍。 

=========================================================================

GITEE相关代码:🌟樊飞 (fanfei_c) - Gitee.com🌟

=========================================================================


1.⼀维前缀和

【模板】前缀和_牛客题霸_牛客网 (nowcoder.com)icon-default.png?t=N7T8https://www.nowcoder.com/practice/acead2f4c28c401889915da98ecdc6bf?tpId=230&tqId=2021480&ru=/exam/oj&qru=/ta/dynamic-programming/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D196

 前缀和:可以快速求出某一段连续区间的和。

本道题目如果使用暴力计算的话会超时,所以需要进行优化。

前缀和解题模板

  1. 第一步:预处理出来一个前缀和数组,比如本题dp[i]表示1-i区间内所有元素的和,且dp[i]=dp[i-1]+arr[i];
  2. 第二步:使用前缀和数组,比如本题求[l,r]区间元素的和就是dp[r]-dp[l-1];

#include <iostream>
#include <vector>
using namespace std;int main() {// 1.输入数据int n,q;cin>>n>>q;vector<int> arr(n+1);for(int i=1;i<=n;i++) cin>>arr[i];// 2.预处理出来一个前缀和数组vector<long long> dp(n+1);for(int i=1;i<=n;i++) dp[i]=dp[i-1]+arr[i]; // 3.使用前缀和数组int l,r;while(q--){cin>>l>>r;cout<<dp[r]-dp[l-1]<<endl;}return 0;
}

 注意:

  • 防止溢出,所以dp数据类型选用long long;
  • 多开一个空间(n+1)是为了防止越界,因为最后需要[l-1],所以下标一般都是以1为起始。

 2.二维前缀和

【模板】二维前缀和_牛客题霸_牛客网 (nowcoder.com)icon-default.png?t=N7T8https://www.nowcoder.com/practice/99eb8040d116414ea3296467ce81cbbc?tpId=230&tqId=2023819&ru=/exam/oj&qru=/ta/dynamic-programming/question-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E7%25AE%2597%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D196


同样的我们使用前缀和解题模板:

  1. 第一步:预处理出来一个前缀和数组,本题中dp[i][j]表示[1,1]-[i][j]区间内所有元素的和。
  2. 第二步:使用前缀和数组。

首先如何得到状态转移方程,即dp[i][j]如何计算?

如图所示:

很明显dp[i][j]=A+B+C+D。

但是A还好说,B和C都不好计算。

那么我们就可以把A、B合并为A+B=dp[i-1][j],把A、C合并为A+C=dp[i][j-1]。

多加了一个A再减去即可。

所以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];


其次如何使用前缀和数组?

同样如上图,[x1][y1]~[x2][y2]的和我们用D块表示。

那么D=A+B+C+D-(A+B)-(A+C)+A=dp[x2][y2]-dp[x1-1][y2]-dp[x2][y1-1]+dp[x1-1][y1-1];


#include <iostream>
#include <vector>
using namespace std;int main() {// 1.输入数据int n,m,q;cin>>n>>m>>q;vector<vector<int>> arr(n+1,vector<int>(m+1));for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)cin>>arr[i][j];// 2.预处理前缀和矩阵vector<vector<long long>> dp(n+1,vector<long long>(m+1));for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){dp[i][j]=dp[i-1][j]+dp[i][j-1]+arr[i][j]-dp[i-1][j-1];}}// 3.使用前缀和矩阵int x1,y1,x2,y2;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;
}

3.练习

724. 寻找数组的中心下标 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/find-pivot-index/238. 除自身以外数组的乘积 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/product-of-array-except-self/560. 和为 K 的子数组 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/subarray-sum-equals-k/

提示:前缀和+哈希表

974. 和可被 K 整除的子数组 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/subarray-sums-divisible-by-k/description/

 补充知识以及思路提示:

1.同余定理

若(a-b)/ p = k ···· 0; //可以整除

则 a % p = b % p;

对于本题来说,我们需要找到可以被k整除的子数组,那么我们假设这段子数组是以i为结尾,x为起始的,整个数组的和为sum,x的前缀和为pre,那么有(sum-pre)%k=0,又因为同余定理可以得到sum%k=pre%k,所以我们只需要将sum%k的结果添加到哈希表中,最后统计哈希表中该余数出现的次数即可,根据后面给出的修正方法,这里求余公式变为(sum%k+k)%k。

2.C++、java对负数 % 正数的结果以及修正

在C++和java语言中负数%正数的结果是一个负数,那么为了让这个负数修正为正数,我们可以利用如下公式:

a为负数,b为正数,那么 修正后的余数 = a % b + b,而为了同一处理正负数,我们可以再对这个结果取模,目的是当a为正数时,也不越界。

所以 修正后的余数 = (a%b+b)% b;


525. 连续数组 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/contiguous-array/

思路提示:

本题让我们找出⼀段连续的区间, 0 和 1 出现的次数相同。
• 如果将 0 记为 -1 , 1 记为 1 ,问题就变成了找出一段区间,这段区间的和等于 0 。
• 于是,就和 『 和为K的子数组』这道题的思路一样了,只不过K的值变为0;


1314. 矩阵区域和 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/matrix-block-sum/

提示:二维前缀和思路


=========================================================================

如果你对该系列文章有兴趣的话,欢迎持续关注博主动态,博主会持续输出优质内容

🍎博主很需要大家的支持,你的支持是我创作的不竭动力🍎

🌟~ 点赞收藏+关注 ~🌟

=========================================================================

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/8094.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【强训笔记】day14

NO.1 思路&#xff1a;用一个哈希表&#xff0c;先遍历s1&#xff0c;统计哈希表内的字符个数&#xff0c;在遍历s2&#xff0c;s2中的字符在哈希表中减去&#xff0c;如果哈希表中的字符个数小于0那么就输出No。 代码实现&#xff1a; #include <iostream> #include&…

森林消防—高扬程水泵:守护绿色屏障的专业利器/恒峰智慧科技

在广袤的森林中&#xff0c;火灾无疑是最具破坏性的灾难之一。为了及时应对森林火灾&#xff0c;保护珍贵的自然资源和生态平衡&#xff0c;高效的消防设备显得尤为重要。森林消防高扬程水泵便是其中一款专业设备&#xff0c;以其高效输送水源的能力&#xff0c;成为守护森林绿…

doris经典bug

在部署完登录web页面查看的时候会发现只有一个节点可以读取信息剩余的节点什么也没读取到 在发现问题后&#xff0c;我们去对应的节点去看log日志&#xff0c;发现它自己绑定到前端的地址上了 现在我们已经发现问题了&#xff0c;以下就开始解决问题 重置doris 首先对be进行操…

使用 Docker 部署 TaleBook 私人书籍管理系统

1&#xff09;项目介绍 GitHub&#xff1a;https://github.com/talebook/talebook Talebook 是一个简洁但强大的私人书籍管理系统。它基于 Calibre 项目构建&#xff0c;具备书籍管理、在线阅读与推送、用户管理、SSO 登录、从百度/豆瓣拉取书籍信息等功能。 友情提醒&#x…

矾液回收矾树脂

五氧化二钒溶液提取矾树脂A-654的过程&#xff0c;是一个涉及五氧化二钒提纯的重要步骤。我们将详细介绍这一提取过程。 首先&#xff0c;我们需要了解五氧化二钒和净化矾树脂A-654的基本性质。五氧化二钒是一种无机化合物&#xff0c; 净化矾树脂A-654 是一款加载了复杂的多胺…

亚马逊最新的 Echo Show 5 和 Show 8

爆爆&#xff01;亚马逊最新智能显示器终于来了&#xff01;Show 8可是一个功能超强的小工具&#xff0c;既能当数码相框、智能家居控制器和闹钟&#xff0c;还能控制您家中的几乎所有设备&#xff01;8英寸的显示屏让您流媒体和视频通话体验更加流畅&#xff01; 如果您不需要…

【Python】京东商品详情数据采集返回商品详情主题主图SKU

文章目录 Python请求 京东API接口 接入文档 接入参数 返回示例 Python请求 # coding:utf-8 """ Compatible for python2.x and python3.x requirement: pip install requests """ from __future__ import print_function import requests…

算法基础01一快速排序,归并排序,二分

一.排序 1.快速 排序 基于分治 确定分界点 左 右 中间 随机划分区间 左半边<x >x在右半边递归处理左右两端 #include<iostream>using namespace std;const int N 1e6 10;int n; int q[N]; void quick_sort(int q[],int l,int r) {if(l>r)return;//边界&…

东莞厂家冷风机的通风降温优点

工业冷风机的通风降温优点主要体现在以下几个方面&#xff1a; 高效降温&#xff1a;工业冷风机采用水蒸发原理&#xff0c;通过将热空气经过湿帘或水幕冷却&#xff0c;能够迅速降低空气温度。这种降温方式相比传统压缩机空调系统更为高效&#xff0c;有助于员工在高温环境中…

【新三个数排序的自创算法,这是我厉年来很满意的一次排序算法设计,最好小于O(N)最坏O((NN/3)/2)。】2024-5-7

缘由如何用C&#xff0b;&#xff0b;解决一下问题_编程语言-CSDN问答 int a[]{1, 4, 7, 8, 5, 2, 3, 6, 9, 7}, n 10, x n, jh 0, j 0;px:if (j < n) {//缘由https://ask.csdn.net/questions/8099444if (--x < 2 j)x n - 1, j 3;if (x < n - 1 && a[x…

档案数字化电子文件检测工具

在档案数字化的过程中&#xff0c;需要注意扫描的电子文件属性和质量是否符合要求。nhdeep电子文件属性检测工具&#xff0c;支持对图片、pdf和ofd文件&#xff0c;显示文件的基本属性&#xff1a;文件类型、文件大小、创建时间&#xff1b;采集文件的分辨率、图片颜色、图片的…

Agent AI智能体:我们的生活即将如何改变?

你有没有想过&#xff0c;那个帮你设置闹钟、提醒你朋友的生日&#xff0c;甚至帮你订外卖的智能助手&#xff0c;其实就是Agent AI智能体&#xff1f;它们已经在我们生活中扮演了越来越重要的角色。现在&#xff0c;让我们一起想象一下&#xff0c;随着这些AI智能体变得越来越…

基于STM32的智能垃圾桶设计(论文+源码)_kaic

基于STM32的智能垃圾桶设计 摘 要 随着社会科学技术的迅猛进展&#xff0c;人们的生活质量和速度也在不断提高。然而&#xff0c;大多数传统的家庭垃圾桶已经过时且缺乏创新&#xff0c;缺乏人性化设计。它们使用起来不方便、不卫生&#xff0c;所有的生活和废物垃圾都被混合…

【XR806开发板试用】阻塞式串口发送与接收教程

本文基于wsl2搭建的ubuntu18.04 vscode编辑器 很奇怪啊&#xff0c;找了半天居然没人发串口的教程&#xff0c;于是只能自己试一试了&#xff0c;在此发一个阻塞式的串口发送与接收的教程。并且&#xff0c;感谢.ACE彭洪权大佬在我配置环境遇到几十个报错的时候帮我远程搭建环…

Python中使用嵌套for循环读取csv文件出现问题

如果我们在使用嵌套循环来读取 CSV 文件时遇到了问题&#xff0c;可以提供一些代码示例和出现的具体错误&#xff0c;这样我可以更好地帮助大家解决问题。不过&#xff0c;现在我可以给大家一个基本的示例&#xff0c;演示如何使用嵌套循环来读取 CSV 文件。 问题背景 我需要读…

I forgot my Plex Account PIN; how can I reset it? How can I change my PIN?

If you’ve set a PIN on your Plex account, it’s possible to reset or remove that PIN. Related Page: Plex Home Regular Plex Account If you know the current PIN If the current PIN is known, then simply edit the current PIN on the Settings > Users &…

torch教程

一 基本用法 1 torch.autograd.Function PyTorch 74.自定义操作torch.autograd.Function - 知乎 (zhihu.com)https://zhuanlan.zhihu.com/p/344802526 虽然pytorch可以自动求导,但是有时候一些操作是不可导的,这时候你需要自定义求导方式。也就是所谓的 "Extending t…

怎样选择IT外包公司?需要注意什么?

随着网络化、数字化、智能化快速发展&#xff0c;一部分企业成立自己的IT部门&#xff0c;负责各个科室的网络安全&#xff0c;大部分企业把网络安全、数据安全&#xff0c;外包给专业的IT外包公司&#xff0c;既提升了办公效率&#xff0c;企业又能把主要精力放在发展核心业务…

BS-Diff | 扩散模型在骨抑制任务上的首次登场!

摘要 胸部 X 射线&#xff08;CXR&#xff09;是肺部筛查中常用的低剂量方式。然而&#xff0c;由于大约 75% 的肺部区域与骨骼重叠&#xff0c;这反过来又阻碍了疾病的检测和诊断&#xff0c;因此 CXR 的功效受到了一定程度的影响。作为一种补救措施&#xff0c;骨抑制技术已…

算法提高之能量项链

算法提高之能量项链 核心思想&#xff1a;区间dp 通过观察发现可以将n个珠子最后的n1个数看作石子 合并石子 在l~r的范围内 找k作隔断 #include <iostream>#include <cstring>#include <algorithm>using namespace std;const int N 110,M N<<…