[Algorithm][前缀和][模板 一维前缀和][模板 二维前缀和][寻找数组中心下标][除自身以外数组的乘积] + 前缀和原理 + 前缀和模板

目录

  • 0.原理讲解
  • 1.[模板]一维前缀和
    • 1.题目链接
    • 2.模板代码实现
  • 2.[模板]二维前缀和
    • 1.题目链接
    • 2.算法原理讲解
    • 3.模板代码实现
  • 3.寻找数组的中心下标
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 4.除自身以外数组的乘积
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现


0.原理讲解

  • 前缀和:快速求出数组中某一个连续区间的和

  • 一维前缀和步骤:

    1. 预处理出来一个前缀和数组

      • dp[i]表示:[1, i]区间内所有元素的和
      • 状态方程转移dp[i] = dp[i - 1] + arr[i]
        请添加图片描述
    2. 使用前缀和数组

      • [l, r] -> dp[r] - dp[l - 1]
        请添加图片描述
  • 二维前缀和步骤:

    1. 预处理出来一个前缀和数组

      • dp[i][j]表示:从[1, 1]位置到[i, j]位置,这段区间里面所有元素的和
      • 状态方程转移dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + arr[i][j] - dp[i - 1][j - 1]
        请添加图片描述
    2. 使用前缀和数组

      • [ x 1 , y 1 ] − [ x 2 , y 2 ] [x_1, y_1] - [x_2, y_2] [x1,y1][x2,y2] -> D = d p [ x 2 ] [ y 2 ] − d p [ x 1 − 1 ] [ y 2 ] − d p [ x 2 ] [ y 1 − 1 ] + d p [ x 1 − 1 ] [ y 1 − 1 ] D = dp[x_2][y_2] - dp[x_1 - 1][y_2] - dp[x_2][y_1 - 1] + dp[x_1 - 1][y_1 -1] D=dp[x2][y2]dp[x11][y2]dp[x2][y11]+dp[x11][y11]
        请添加图片描述
  • 为什么下标要从1开始计数?

    • 为了处理边界情况
      • 倘若l == 0,那么使用前缀和数组时就会出现dp[r] - dp[-1]
      • 但此时若从1开始计数,则为dp[2] - dp[0],此时不会出现任何问题
    • arr[0] = 0是不会影响其他值的

1.[模板]一维前缀和

1.题目链接

  • [模板]一维前缀和

2.模板代码实现

int main()
{int n = 0, q = 0;cin >> n >> q;vector<int> arr(n + 1);for(int i = 1; i <= n; i++){cin >> arr[i];}// 预处理出来一个前缀和数组vector<long long> dp(n + 1);for(int i = 1; i <= n; i++){dp[i] = dp[i - 1] + arr[i];}// 使用前缀和数组int l = 0, r = 0;while(q--){cin >> l >> r;cout << dp[r] - dp[l - 1] << endl;}return 0;
}

2.[模板]二维前缀和

1.题目链接

  • [模板]二维前缀和

2.算法原理讲解

  • 类⽐于⼀维数组的形式,如果能处理出来从[1, 1]位置到[i, j]位置这⽚区域内所有元素的累加和,就可以在 O ( 1 ) O(1) O(1)的时间内,搞定矩阵内任意区域内所有元素的累加和

3.模板代码实现

int main()
{int n = 0, m = 0, q = 0;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];}}// 预处理前缀和矩阵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];}}// 使用预处理数组int x1 = 0, y1 = 0, x2 = 0, y2 = 0;long long ret = 0;while(q--){cin >> x1 >> y1 >> x2 >> y2;ret = dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1];cout << ret << endl;;}return 0;
}

3.寻找数组的中心下标

1.题目链接

  • 寻找数组的中心下标

2.算法原理详解

  • 由本题可感受出:前缀和类型的题不要硬套模板,题目问什么,根据题目,去微调模板就可以
    • 比如[0, i - 1]中的最大值,也可以用前缀和思想
  • 从中⼼下标的定义可知,除中⼼下标的元素外,该元素左边的**「前缀和」等于该元素右边的「后缀和」**
    • 因此,可以先预处理出来两个数组,⼀个表⽰前缀和,另⼀个表⽰后缀和
    • 然后,可以循环枚举可能的中⼼下标,判断每⼀个位置的「前缀和」以及 「后缀和」,如果⼆者相等,就返回当前下标
  • 前缀和数组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]
  • 细节处理
    • f[0] = 0g[n - 1] = 0
    • f -> 从左向右 / g -> 从右向左
      请添加图片描述

3.代码实现

int PivotIndex(vector<int>& nums) 
{int n = nums.size();vector<int> f(n), g(n);// 预处理前缀和数组和后缀和数组// f[i] -> [0, i - 1]区间,所有元素的和for(int i = 1; i < n; i++){f[i] = f[i - 1] + nums[i - 1];}// g[i] -> [i + 1, n - 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;
}

4.除自身以外数组的乘积

1.题目链接

  • 除自身以外数组的乘积

2.算法原理详解

  • 前缀积数组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]
  • 细节处理
    • f[0] = 1,g[n - 1] = 1`
    • f -> 从左向右 / g -> 从右向左
      请添加图片描述

3.代码实现

vector<int> productExceptSelf(vector<int>& nums) 
{int n = nums.size();vector<int> f(n), g(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];}// 使用vector<int> ret(n);for(int i = 0; i < n; i++){ret[i] = f[i] * g[i];}return ret;
}

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

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

相关文章

Docker学习(二十五)构建 Arthas 基础镜像

目录 一、简介二、构建基础镜像2.1 下载 Arthas2.2 编写 Dockerfile2.3 构建镜像2.4 创建容器2.5 测试 一、简介 Arthas 是一款由 阿里巴巴 开发的 线上监控诊断工具。通过全局视角实时查看应用负载、内存、GC、线程等信息&#xff0c;能在不修改代码的情况下&#xff0c;对业…

Pytorch常用的函数(八)常见优化器SGD,Adagrad,RMSprop,Adam,AdamW总结

Pytorch常用的函数(八)常见优化器SGD,Adagrad,RMSprop,Adam,AdamW总结 在深度学习中&#xff0c;优化器的目标是通过调整模型的参数&#xff0c;最小化&#xff08;或最大化&#xff09;一个损失函数。 优化器使用梯度下降等迭代方法来更新模型的参数&#xff0c;以使损失函数…

【QT进阶】Qt http编程之实现websocket server服务器端

往期回顾 【QT进阶】Qt http编程之json解析的简单介绍-CSDN博客 【QT进阶】Qt http编程之nlohmann json库使用的简单介绍-CSDN博客 【QT进阶】Qt http编程之websocket的简单介绍-CSDN博客 【QT进阶】Qt http编程之实现websocket server服务器端 一、最终效果 通过ip地址和端口…

人工智能时代的关键技术:深入探索向量数据库及其在AI中的应用

文章目录 1. 理解向量数据库&#xff1a;二维模型示例2. 向量数据库中的数据存储与检索3. 向量数据库如何工作&#xff1f;4. 向量数据库如何知道哪些向量相似&#xff1f; 在人工智能技术日益成熟的当下&#xff0c;向量数据库作为处理和检索高维数据的关键工具&#xff0c;对…

Dropout Feature Ranking for Deep Learning Models

摘要 深度神经网络( deep neural networks&#xff0c;DNNs )在多个领域取得了最新的研究成果。不幸的是&#xff0c;DNNs因其不可解释性而臭名昭著&#xff0c;从而限制了其在生物和医疗保健等假说驱动领域的适用性。此外&#xff0c;在资源受限的环境下&#xff0c;设计依赖…

Linux下的UDEV机制/守护进程

一. Udev机制概念引入 ( 需要在 etc/udev/rules.d/ 下创建设备的相关规则&#xff0c;不然有可能udev机制生成的设备文件不具备可读可写的权限&#xff0c;adb无法成功通过该设备文件访问设备 ) a. 创建文件夹 sudo vim Xiaomi-audroid.rules b. 添加规则 …

在vscode上面进行分支merge的记录

前言&#xff1a;在我们的项目中&#xff0c;有两个分支&#xff1a;master和liutielong。现在要将liutielong分支的改动merge到master分支中。 如果master分支已经更改了&#xff0c;所以要先pull&#xff08;这是在git bash里面的命令&#xff09;。 git pull origin master…

5分钟——快速搭建后端springboot项目

5分钟——快速搭建后端springboot项目 1. idea新建工程2. 构建pom.xml文件3. 构建application.yml配置文件4. 构建springboot启动类5. 补充增删改查代码6. 运行代码 1. idea新建工程 点击右上角新建一个代码工程 别的地方不太一样也不用太担心&#xff0c;先创建一个工程就好…

学习配置文件

1.yml的语法格式问题&#xff1a; 2.配置文件获取数据&#xff1a; Value方式&#xff1a; Environment&#xff1a; 获取自定义对象的方式&#xff1a; 设置get和set方法&#xff0c;还有toString方法。 3. 日志配置&#xff1a; logo的配置&#xff1a; 日志插件&#xff…

汽车纵染压制专用液压机比例阀放大器

汽车纵染压制专用液压机比例阀放大器是一种专门用于汽车纵梁拉伸工艺的设备&#xff0c;它也可以用于其他金属薄板的压制成型及校正工艺。该类型的液压机通常具备独立的动力机构和电气系统&#xff0c;采用PLC技术进行控制&#xff0c;以确保操作的准确性和稳定性。除了纵梁拉伸…

【iOS】分类,扩展与关联对象

文章目录 前言一、分类实现原理二、分类加载流程三、扩展四、类别与类扩展的区别五、关联对象动态添加取值移除关联对象应用 总结 前言 上一篇章我们探究了类与对象的底层&#xff0c;这一篇我们探究一下分类&#xff0c;扩展与关联对象 一、分类实现原理 首先我们知道扩展是…

CentOS-7安装grafana

一、通用设置&#xff08;分别在4台虚拟机设置&#xff09; 1、配置主机名 hostnamectl set-hostname --static 主机名2、修改hosts文件 vim /etc/hosts 输入&#xff1a; 192.168.15.129 master 192.168.15.133 node1 192.168.15.134 node2 192.168.15.136 node33、 保持服…

GaussianEditor:快速可控的3D编辑与高斯飞溅

GaussianEditor: Swift and Controllable 3D Editing with Gaussian Splatting GaussianEditor&#xff1a;快速可控的3D编辑与高斯飞溅 Yiwen Chen*​1,2   Zilong Chen*​3,5   Chi Zhang2   Feng Wang3   Xiaofeng Yang2 陈怡雯 *​1,2 陈子龙 *​3,5 张驰 2 王峰 3 杨晓…

MySQL学习笔记7——视图和存储过程

视图和存储过程 一、视图1、视图的作用2、如何操作视图和视图中的数据3、视图的优缺点 二、存储过程1、如何创建存储过程2、调用存储过程3、修改和删除存储过程 一、视图 1、视图的作用 视图是一种虚拟表&#xff0c;我们可以把一段查询语句作为视图存储在数据库中&#xff0…

liqo学习及安装,k8s,kubernetes多集群互联

先按照官方的教程在虚拟机安装学习 在开始以下教程之前&#xff0c;您应该确保您的系统上安装了以下软件&#xff1a; Docker&#xff0c;容器运行时。Kubectl&#xff0c;Kubernetes 的命令行工具。 curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.…

基于Python利用zhconv模块进行简繁体字转换

在处理中文文本时&#xff0c;简繁体字之间的转换是一项常见的任务。Python提供了许多库来实现这个目的&#xff0c;其中之一就是zhconv。zhconv是一个Python库&#xff0c;提供了简体字和繁体字之间的转换功能。本教程将向你展示如何使用zhconv模块来实现简繁体字的互转&#…

Redis底层数据结构之Dict

目录 一、概述二、Dict结构三、Dictht结构四、DictEntry结构五、核心特性 上一篇文章 reids底层数据结构之quicklist 一、概述 Redis 的 Dict 是一个高效的键值对映射数据结构&#xff0c;采用双哈希表实现以支持无锁的渐进式 Rehash&#xff0c;确保扩容或缩容时的高效性能。…

想冲宇宙厂,直接挂了。。。

宇宙厂实际是字节&#xff0c;这个称呼是因为字节跳动主宰了宇宙内一切App&#xff0c;有点家大业大的意思。 今天分享一位字节春招凉经&#xff0c;问了一些数据库和Java八股&#xff0c;没出算法题&#xff0c;直接挂了&#xff0c;竟然最喜欢出算法题的字节&#xff0c;这次…

iptables实现docker容器动态端口映射实操

背景 之前在《Docker 动态修改容器端口映射的方法》一文中&#xff0c;说明了如何使用修改配置和加防火墙规则实现动态端口映射。但是没有具体分享加防火墙实现动态端口映射的实际案例。今天就分享一下实际操作案例&#xff0c;供大家参考。 分析 动态端口映射的用途 容器端口…

(2024)Visual Studio的介绍、安装与使用

Visual Studio介绍 1.Visual Studio是什么&#xff1f; Visual Studio是微软公司推出的一款开发工具包系列产品&#xff0c;它是一个基本完整的开发工具集&#xff0c;为软件开发者提供了整个软件生命周期中所需的大部分工具。 2.Visual Studio的定义 Visual Studio是美国微软公…