【寻找one piece的算法之路】前缀和(一)

news2024/10/27 19:16:15

💐个人主页:初晴~

📚相关专栏:寻找one piece的刷题之路


什么是前缀和?

主要是通过预先计算数组或矩阵的前缀和,来快速查询子数组或子矩阵的和。这种算法可以用空间换时间,提高查询效率。

概念

给定一个数组 A,前缀和数组 PP 定义为:

P[i]=A[0]+A[1]+⋯+A[i]P[i]=A[0]+A[1]+⋯+A[i]

即 P[i]P[i] 是从数组开头到位置 ii 所有元素的和

计算前缀和

  1. 初始化:前缀和数组的第一个元素等于原数组的第一个元素,即 P[0]=A[0]。
  2. 迭代计算:对于每一个 i>0,计算 P[i]=P[i−1]+A[i]P[i]=P[i−1]+A[i]。

查询区间和

一旦前缀和数组构建完成,查询区间和的操作变得非常简单。如果要查询数组 AA 中从索引 ll 到索引 rr 的区间和,可以使用以下公式:

sum(l,r)=P[r]−P[l−1]sum(l,r)=P[r]−P[l−1]

注意,这里的 l−1 必须是非负的,因此查询的左端点 l 至少为 1(对于从 0 开始索引的数组,l 至少为 0)。

时间复杂度

  • 预处理时间复杂度:构建前缀和数组的时间复杂度为 O(n),其中 n 是数组的长度。
  • 查询时间复杂度:查询区间和的时间复杂度为 O(1),因为只需要一次简单的计算。

一、⼀维前缀和

题目链接

题目描述:

题目分析:

先准备一个数组dp【】来存储前缀和,dp【i】表示【1,i】区间内所有元素的和。我们可以通过一次遍历就求出前缀和数组,通过dp【i】=dp【i-1】+arr【i】来递推。

之后就可以通过前缀和数组快速求出“某一段区间”内所有元素的和

比如我们要查询区间【l,r】时,区间内元素和就为:dp【r】-dp【l-r】;

代码实现:

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n=in.nextInt(),q=in.nextInt();
        long[] arr=new long[n+1];
        for(int i=1;i<=n;i++){
            arr[i]=arr[i-1]+in.nextInt();
        }
        for(int i=0;i<q;i++){
            int l=in.nextInt();
            int r=in.nextInt();
            System.out.println(arr[r]-arr[l-1]);
        }
    }
}

二、二维前缀和

题目链接

题目描述:

题目分析:

问题的关键在于我们能否搞出一个数组nums【】【】,让nums【i】【j】代表重【0,0】到【i,j】区域内所有元素的和。这样就有机会在O(1)的时间复杂度下快速查询出任意区域的元素和。

我们可以通过下图的方法建立前缀和数组,目的是为了避免繁琐的边界判定。这样下标从1开始填写,我们就能放心地使用【i-1】【j-1】下标的位置了:

我们可以将【0,0】到【i,j】区域划分为以下几块位置:

nums【i】【j】=红+篮+粉+绿

1、绿色区域的值就是arr【i】【j】的值

2、红+篮区域的值事实上就是【0,0】到【i-1,j】区域内的元素和,即nums【i-1】【j】

3、红+粉区域的值事实上就是【0,0】到【i,j-1】区域内的元素和,即nums【i】【j-1】

4、而红色区域的值事实上就是【0,0】到【i-1,j-1】区域内的元素和,即nums【i-1】【j-1】

这样我们就可以得到整个区域的元素和,就等于 红蓝+红粉-红+绿

也就可以得到 nums[i][j]=nums[i-1][j]+nums[i][j-1]-nums[i-1][j-1]+arr[i][j]

这样我们就可以通过一次遍历求出前缀和数组了。

求出前缀和数组后,我们还得想办法通过前缀和数组来查询计算出任意一块区域的元素和

类似的,我们可以划分出如下几个区域:

我们的目的就是求出绿色区域【x1,y1】到【x2,y2】区域内元素的和

由于我们已经求出前缀和了,于是我们可能得到一下区域的值:

1、红蓝粉绿 整个区域的元素和为nums【x2,y2】

2、红蓝 区域的元素和为 nums【x1-1】【y2】

3、红粉 区域的元素和为 nums【x2】【y1-1】

4、红色区域的元素和为 nums【x1-1】【y1-1】

这样,我们就可以得到绿色区域值等于 红蓝粉绿-红蓝-红粉+红

也就是 ans=nums[x2][y2]-nums[x2][y1-1]-nums[x1-1][y2]+nums[x1-1][y1-1]

代码实现:

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n=in.nextInt(),m=in.nextInt(),q=in.nextInt();
        int[][] arr=new int[n+1][m+1];
        long[][] nums=new long[n+1][m+1];
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                arr[i][j]=in.nextInt();
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                nums[i][j]=nums[i-1][j]+nums[i][j-1]-nums[i-1][j-1]+arr[i][j];
            }
        }
        for(int i=0;i<q;i++){
            int x1=in.nextInt();
            int y1=in.nextInt();
            int x2=in.nextInt();
            int y2=in.nextInt();
            System.out.println(nums[x2][y2]-nums[x2][y1-1]-nums[x1-1][y2]+nums[x1-1][y1-1]);
        }
    }
}

三、寻找数组的中心下标

题目链接

题目描述:

题目分析:

从中⼼下标的定义可知,除中⼼下标的元素外,该元素左边的「前缀和」等于该元素右边的「后缀
和」。
事实上,我们并不需要遍历两次分别求出前缀和 和 后缀和,可以通过一些技巧优化一下。
通过两个变量 l 和 r,分别该坐标 i 前后的 前缀和 和 后缀和。
  • 先遍历一遍数组,让 r 记录下整个数组的元素和。
  • 接着再进行一次遍历,让 r 减去当前遍历元素的值,这样,r 就能表示 i 坐标后的后缀和,
  • 然后比较此时 l 和 r 的值,如果相等,就声明找到目标位置了,直接返回;如果不相等,则让 l 加上当前遍历元素的值,这样 l 也就能表示遍历途中 的前缀和了
  • 重复上述步骤,就能解决题目要求了

代码实现:

class Solution {
    public int pivotIndex(int[] nums) {
        int n=nums.length,l=0,r=0;
        for(int num:nums){
            r+=num;
        }
        for(int i=0;i<n;i++){
            r-=nums[i];
            if(l==r)return i;
            l+=nums[i];
        }
        return -1;
    }
}


四、除自身以外数组的乘积

题目链接

题目描述:

题目分析:

注意题⽬的要求,不能使⽤除法,并且要在 O(N) 的时间复杂度内完成该题。那么我们就不能使
⽤暴⼒的解法,以及求出整个数组的乘积,然后除以单个元素的⽅法。
继续分析,根据题意,对于每⼀个位置的最终结果 ret[i] ,它是由两部分组成的:
  • nums[0] * nums[1] * nums[2] * ... * nums[i - 1]
  • nums[i + 1] * nums[i + 2] * ... * nums[n - 1]
于是,我们可以利⽤前缀和的思想,使⽤两个数组 qian 和 hou,分别处理出来两个信息:
  • qian 表⽰:i 位置之前的所有元素,即 [0, i - 1] 区间内所有元素的前缀乘积,
  • hou 表⽰: i 位置之后的所有元素,即 [i + 1, n - 1] 区间内所有元素的后缀乘积
然后再处理最终结果。

代码实现:

class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n=nums.length;
        int[] answer=new int[n];
        int[] qian=new int[n],hou=new int[n]; 
        qian[0]=1;
        hou[n-1]=1;
        for(int i=1;i<n;i++){
            qian[i]=qian[i-1]*nums[i-1];
        }
        for(int i=n-2;i>=0;i--){
            hou[i]=hou[i+1]*nums[i+1];
        }
        for(int i=0;i<n;i++){
            answer[i]=qian[i]*hou[i];
        }
        return answer;
    }
}

那么本篇文章就到此为止了,如果觉得这篇文章对你有帮助的话,可以点一下关注和点赞来支持作者哦。如果有什么讲的不对的地方欢迎在评论区指出,希望能够和你们一起进步✊

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

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

相关文章

FileOutputStream类

1.操作本地文件的字节输出流&#xff0c;可以把程序中的数据写到本地文件中。 2.书写步骤&#xff1a; 3.实例代码 结果&#xff1a;可以看到my io下面已经生成了一个a.txt文件。 4.注意细节 &#xff08;1&#xff09;参数是字符串表示的路径或者是File对象 &#xff08;2&…

怎么把音频的速度调慢?6个方法调节音频速度

怎么把音频的速度调慢&#xff1f;调慢音频速度不仅可以帮助我们更好地捕捉细节&#xff0c;还能让我们在分析和学习时更加从容。这对于音乐爱好者来说&#xff0c;尤其有助于理解复杂的旋律和和声&#xff0c;使学习过程变得更加高效。而在语言学习中&#xff0c;放慢语速则能…

Spring Cloud 3.x 集成eureka快速入门Demo

1.什么是eureka&#xff1f; Eureka 由 Netflix 开发&#xff0c;是一种基于REST&#xff08;Representational State Transfer&#xff09;的服务&#xff0c;用于定位服务&#xff08;服务注册与发现&#xff09;&#xff0c;以实现中间层服务的负载均衡和故障转移&#xff…

基于webrtc实现音视频通信

与传统通信方式不同&#xff0c;p2p通信的实现过程不依赖于中间服务器的信息收发&#xff0c;直接通过信令等完成通信过程的建立&#xff1b; 通过websocket实现信令服务器的建立&#xff0c;而通过信令来确定通信双方&#xff1b; webrtc通过 sdp协议来完善通信双方间协议的…

React01 开发环境搭建

React 开发环境搭建 一、创建 React 项目二、项目精简 一、创建 React 项目 执行下述命令创建 react 项目 blu-react-basis npx create-react-app blu-react-basis项目目录结构如下&#xff1a; 执行下述命令启动项目 npm run start启动效果如下&#xff1a; 二、项目精简 …

Java Agent 技术解析

什么是Java Agent Java Agent是在 JDK1.5 引入的一种可以动态修改 Java 字节码的技术。Java 类编译之后形成字节码被 JVM 执行&#xff0c;在 JVM 在执行这些字节码之前获取这些字节码信息&#xff0c;并且通过字节码转换器对这些字节码进行修改&#xff0c;来完成一些额外的功…

维生素对于生活的重要性

在探索健康奥秘的旅途中&#xff0c;维生素作为人体不可或缺的微量营养素&#xff0c;扮演着至关重要的角色。它们虽不直接提供能量&#xff0c;却是酶促反应、细胞代谢、免疫功能乃至心理健康的基石。今天&#xff0c;让我们一同深入探讨人体所需补充的维生素&#xff0c;这些…

Keepalived高可用和Haproxy负载均衡

一、概念 简介 keepalived是集群管理中保证集群高可用的一个服务软件&#xff0c;用来防止单点故障。 工作原理 keepalived是以VRRP协议为实现基础的&#xff0c;N台路由器组成一个路由器组。master上有一个对外提供服务的vip&#xff0c;master会向backup进行发送组播&…

4.stable-diffusion-webui1.10.0--图像修复(adetailer)插件

ADetailer是Stable Diffusion WebUI的一个插件&#xff0c;它通过深度学习模型智能检测图像中的人脸、手部及身体等关键部位&#xff0c;并自动进行重绘修复&#xff0c;使得生成的图像更加自然、符合预期。 ADetailer插件主要应用于图像的细节增强、降噪和修复&#xff0c;特…

Git-bug001 VScode中git clone的地址首次push报错push.default is unset

问题现象&#xff1a; 解释&#xff1a;Git 提醒用户 push.default 配置未设置&#xff0c;且其隐式值已在最新版本的 Git 中更改 解决-输入&#xff1a;git config --global push.default simple 然后重新push就可以了 然后继续报问题&#xff1a;点击OK即可 解释&#xff1…

计算机网络(十一) —— 数据链路层

目录 一&#xff0c;关于数据链路层 二&#xff0c;以太网协议 2.1 局域网 2.2 Mac地址 2.3 Mac帧报头 2.4 MTU 三&#xff0c;ARP协议 3.1 ARP是什么 3.2 ARP原理 3.3 ARP报头 3.4 模拟ARP过程 3.5 ARP周边问题 四&#xff0c;NAT技术 4.1 NAT技术背景 4.2 NAT转…

Windows11安装CUDA、cuDNN、PyTorch详解

目录 CUDA查看 CUDA下载 CUDA安装 cuDNN安装 PyTorch安装 复现环境&#xff1a; 系统版本CUDA12.3cuDNN9.5.0Python3.9PyTorch2.3.1Windows11 CUDA查看 首先我们需要看一下操作系统是否支持GPU。打开任务管理器&#xff0c;点击性能&#xff0c;如图&#xff1a; 这表明作…

RabbitMQ 入门(二)入门案例

一、RabbitMQ的基本结构、角色和消息模型 MQ的基本结构&#xff1a; RabbitMQ中的一些角色&#xff1a; - publisher&#xff1a;生产者 - consumer&#xff1a;消费者 - exchange个&#xff1a;交换机&#xff0c;负责消息路由 - queue&#xff1a;队列&#xff0c;存储消息…

智汇云舟亮相WAFI世界农业科技创新大会,并参编数字农业产业图谱

10月10日&#xff0c;2024WAFI世界农业科技创新大会农食行业创新与投资峰会在北京金海湖国际会展中心举行。中国农业大学MBA教育中心主任、教授付文阁、平谷区委常委、统战部部长刘堃、华为公共事业军团数字政府首席专家刘丹、荷兰瓦赫宁根大学前校长Aalt Dijkhuizen、牧原食品…

iPad备份软件哪个好?好用的苹果备份软件推荐

苹果手机在将数据备份到电脑时&#xff0c;需要通过第三方的管理软件&#xff0c;才可以将手机连接到电脑进行备份。苹果手机备份软件有很多&#xff0c;常用的有&#xff1a;爱思助手、iMazing、iTuns等。那么这三款常用的备份软件究竟哪款更好呢&#xff1f;下面就给大家盘点…

Docker 容器跨主机通信 overlay

Docker 容器跨主机通信 overlay 一.Overlay网络概述 ​ Overlay网络是指在不改变现有网络基础设施的前提下&#xff0c;通过某种约定通信协议&#xff0c;把二层报文封装在IP报文之上的新的数据格式。Overlay网络采用VXLAN&#xff08;Virtual Extensible LAN&#xff09;技术…

通过docker镜像安装elasticsearch和kibana

目录 前言安装elasticsearch:7.17.21安装对应版本的kibana 前言 本文主要参考&#xff1a;https://blog.csdn.net/qq_23859799/article/details/138521052&#xff0c;内容基本一致&#xff0c;改动了部分错误 安装elasticsearch:7.17.21 拉取镜像&#xff1a;docker pull d…

论文 | Context-faithful Prompting for Large Language Models

主要内容&#xff1a; 这篇文章主要探讨了如何提高大型语言模型 (LLM) 在特定语境下的“忠诚度”&#xff0c;即模型是否能准确理解并提供与上下文相符的答案。文章关注了两个主要问题&#xff1a; 知识冲突&#xff1a; 当上下文中的事实与模型预训练数据中的事实不一致时&a…

树莓派应用--AI项目实战篇来啦-17.YOLOv8目标检测-安全帽检测

1. YOLOv8介绍 YOLOv8是Ultralytics公司2023年推出的Yolo系列目标检测算法&#xff0c;可以用于图像分类、物体检测和实例分割等任务。YOLOv8作为YOLO系列算法的最新成员&#xff0c;在损失函数、Anchor机制、样本分配策略等方面进行了全面优化和创新。这些改进不仅提高了模型的…

WebGl学习使用attribute变量绘制一个水平移动的点

在WebGL编程中&#xff0c;attribute变量是一种特殊类型的变量&#xff0c;用于从客户端传递数据到顶点着色器。这些数据通常包括顶点的位置、颜色、纹理坐标等&#xff0c;它们是与每个顶点直接相关的信息。attribute变量在顶点着色器中声明&#xff0c;并且对于每个顶点来说都…