优选算法的睿智之林:前缀和专题(一)



专栏:算法的魔法世界
个人主页:手握风云
目录
一、前缀和
二、例题讲解
2.1. 一维前缀和
2.2. 二维前缀和
2.3. 寻找数组的中心下标
2.4. 除自身以外数组的乘积
一、前缀和
前缀和算法是一种用于处理数组或序列数据的算法,其核心思想是通过预先计算出数组中每个位置之前所有元素的和(即前缀和),从而快速解决一些与区间和相关的问题。它在处理数组求和、区间统计等场景下非常高效。
二、例题讲解
2.1. 一维前缀和

我们需要注意一个细节,上面题目的数组给定下标是从1开始的。我们先来想一个暴力解法——模拟。每次查询都从l下标一直遍历到r下标,最坏情况下就是q次都是从头遍历到尾,所以暴力解法的时间复杂度为,n、q的最大值都为
,一定会超时。
第二种解法就是利用前缀和算法。第一步,我们先预处理出一个前缀和数组int[] dp,dp[i]代表的是arr数组区间[1,i]的和。而数组dp中每一个元素的算法不用再从头加到尾,直接利用递推公式dp[i] = dp[i-1] + arr[i]。

第二步是利用前缀和数组。比如我们要计算[2,5]区间的和,我们没必要直接访问下标2——5。根据下图可以得出,dp[r] - dp[l-1]。我们预处理前缀和的时间复杂度为,每次查询可以直接获取下标,那么q次查询的时间复杂度为
,整体时间复杂度为
。

前面提到了一个细节,就是数组下标为什么要从1开始?如果我们要查询[0,2]区间的和,那么l-1就会为-1,就会无法访问到数组的第一个元素,从而方便处理边界问题。
完整代码实现:
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);while (in.hasNextInt()) {int n = in.nextInt(), q = in.nextInt();int[] arr = new int[n + 1];for (int i = 1; i < n + 1; i++) {arr[i] = in.nextInt();}//预处理一个前缀和数组long[] dp = new long[n + 1];for (int i = 1; i < n + 1; i++) {dp[i] = dp[i - 1] + arr[i];}//使用前缀和数组while (q > 0) {int l = in.nextInt(), r = in.nextInt();System.out.println(dp[r] - dp[l - 1]);q--;}}}
}
2.2. 二维前缀和

暴力解法与上一道题一样,也是利用模拟在指定区间内遍历,时间复杂度为。跟上一道题一样,也是会超时的。
同一维前缀和一样,我们第一步还是先预处理一个与给定矩阵arr[][]同等规模的前缀和矩阵。dp[i][j]里的每个元素代表着矩阵arr[][]的阴影面积。

关于如何求出dp[i][j]的值,我们没有必要再去遍历矩阵arr,因为遍历的时间复杂度会与暴力求解的一样高。我们可以利用完全平方公式的思想,下图中的元素之和,就是四个区域A、B、C、D的和。A区域的和可以很好的算出来:dp[i-1][j-1],但是B、C区域的和又不好算了。我们退而求其次,利用A+B+A+C-A的来算。A+B:dp[i-1][j];A+C:dp[i][j-1]。

第二步就是利用二维前缀和矩阵。题目要求我们算出(x1,y1)——(x2,y2)里面的值直接A+B+C+D-(A+B)-(A+C)+A求出结果。

完整代码实现:
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);//1. 读取输入的数据int n = in.nextInt(), m = in.nextInt(), q = in.nextInt();int[][] arr = new int[n + 1][m + 1];for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {arr[i][j] = in.nextInt();}}//2. 预处理一个前缀和矩阵long[][] dp = new long[n + 1][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. 使用前缀和矩阵while (q-- > 0) {int x1 = in.nextInt(), y1 = in.nextInt(), x2 = in.nextInt(), y2 = in.nextInt();System.out.println(dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1]);}}
}
2.3. 寻找数组的中心下标

本题是要我们查找一个下标,这个下标左侧的元素之和与右侧的元素之和相等。如果存在这样一个下标则返回这个下标值,如果没有返回-1。
我们先来思考暴力解法。枚举每一个下标,计算左侧的元素之和与右侧的元素之和是否相等。我们需要从头到尾遍历数组下标,再去遍历左侧和右侧的元素,所以时间复杂度为。
接下来对暴力解法进行优化。我们需要求的是某段数组元素的和,那么就可以利用前缀和思想,i左侧的元素之和f(i) = f(i-1) + nums[i-1],i右侧的元素之和g(i) = g(i+1) + nums[i+1]。只要比较出f(i) = g(i),就返回i。
还有一些细节:1. 防止数组越界访问,如果i=0,那么f(i-1)就是[-1,0]这段区间的和,f(0)=0;同理,g(n-1)=0。2. f是依赖与i-1,所以f数组是从左向右填写;g是依赖于i+1,所以g数组是从右向左填写的。

完整代码实现:
public class Solution {public int pivotIndex(int[] nums) {int n = nums.length;int[] f = new int[n];int[] g = new int[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;}
}
2.4. 除自身以外数组的乘积

暴力解法与上一题类似,枚举数组下标,再遍历下标的左右两侧计算乘积。时间复杂度也与上一题一样,也是。
利用前缀和的思想,预处理出i左侧区间的乘积和右侧区间的乘积,到某个下标时,直接从前缀与后缀里进行拿值就可以。算法原理与上一题完全一样的,只不过这道题是要求乘积。前缀积f[i] = f[i - 1] * nums[i - 1];g[i] = g[i+1] * nums[i+1]。细节处理上,与上一题不同的是,边界f[0]与g[n-1]要赋值成1。

完整代码实现:
public class Solution {public int[] productExceptSelf(int[] nums) {int n = nums.length;int[] f = new int[n];int[] g = new int[n];f[0] = 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];int[] ret = new int[n];for (int i = 0; i < n; i++)ret[i] = f[i] * g[i];return ret;}
}相关文章:
优选算法的睿智之林:前缀和专题(一)
专栏:算法的魔法世界 个人主页:手握风云 目录 一、前缀和 二、例题讲解 2.1. 一维前缀和 2.2. 二维前缀和 2.3. 寻找数组的中心下标 2.4. 除自身以外数组的乘积 一、前缀和 前缀和算法是一种用于处理数组或序列数据的算法,其核心思想是…...
嵌入式八股文学习——STL相关内容学习
文章目录 map和set的区别与实现1. map和set的区别2. 为什么set的元素和map的key不可修改? map和set的实现1. map的实现原理map的操作:map的特点: 2. set的实现原理set的操作:set的特点: map和set的底层原理(…...
【清华大学】AIGC发展研究(3.0版)
目录 AIGC发展研究报告核心内容一、团队简介二、AI哲学三、国内外大模型四、生成式内容(一)文本生成(二)图像生成(三)音乐生成(四)视频生成 五、各行业应用六、未来展望 AIGC发展研究…...
JavaSE1.0(基础语法之运算符)
算术运算符 基础运算之加 减 乘 除 取余( - * / %) 运算符之相加( ) public static void main(String[] args) {System.out.println("Hello world!");int a 10;int b 20;int c a b;System.out.println(c);//…...
二十五、实战开发 uni-app x 项目(仿京东)- 前后端轮播图
定义了一个名为 Swiper 的Java类,用于表示一个轮播图实体。它使用了 Jakarta Persistence API (JPA) 来映射数据库表,并使用了 Lombok 库来简化代码。以下是对代码的详细讲解: 1. 包声明 package com.jd.jdmall.model; 这行代码声明了该类所在的包路径为 com.jd.jdmall.mode…...
ubuntu设置开机自动运行应用
系统版本:Ubuntu 24.04.1 LTS桌面版 按招网上的资料显示,当前版本主要的实现方式有以下两种, 方式1:通过图形界面的【启动应用程序】设置开机自启动;方式2:配置为服务实现开机自启动。 但是在我的电脑上方…...
蓝桥与力扣刷题(蓝桥 数的分解)
题目:把 2019分解成 3个各不相同的正整数之和,并且要求每个正整数都不包含数字 2 和 4,一共有多少种不同的分解方法? 注意交换 3 个整数的顺序被视为同一种方法,例如 1000100118和 1001100018 被视为同一种。 解题思…...
用ACM模式模板刷hot100
面试手撕给的模板基础上写 给的模板一般是下面这样 把while内容删除(一般刷hot100题目输入不需要同时输入几组) 第一个方法里写处理输入输出 自己再写一个方法,就是力扣里的核心代码(加上static) 第一个处理输入输…...
Java IO 流:从字节到字符再到Java 装饰者模式(Decorator Pattern),解析与应用掌握数据流动的艺术
在 Java 编程中,IO(输入输出)流是处理数据输入输出的核心工具。无论是读取文件、网络通信,还是处理用户输入,IO 流都扮演着重要角色。本文将深入探讨 Java IO 流的核心概念、分类、经典代码实例及其应用场景࿰…...
爬虫案例-爬取某站视频
文章目录 1、下载FFmpeg2、爬取代码3、效果图 1、下载FFmpeg FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。 点击下载: ffmpeg 安装并配置 FFmpeg 步骤: 1.下载 FFmpeg: 2.访问 FFmpeg 官网。 3.选择 Wi…...
nacos-未经授权创建用户漏洞
1、修改配置文件 vim application.properties# 修改配置项 nacos.core.auth.enabledtrue nacos.core.auth.enable.userAgentAuthWhitefalse2、重启nacos systemctl restart nacos3、验证 打开nacos部署服务器输入命令 curl -XPOST -d “usernametest123&passwordtest!123…...
C++:IO库
一、C IO库的架构 C标准库中的IO系统基于流(Stream)的概念,分为三层结构: 流对象(如cin, cout, fstream)流缓冲区(streambuf,负责底层数据处理)数据源/目的…...
企业级前端架构设计与实战
一、架构设计核心原则 1.1 模块化分层架构 典型目录结构: src/├── assets/ # 静态资源├── components/ # 通用组件├── pages/ # 页面模块├── services/ # API服务层├── store/ # 全局状态管理├── uti…...
从入门到精通【MySQL】 CRUD
文章目录 📕1. Create 新增✏️1.1 单行数据全列插入✏️1.2 单行数据指定列插入✏️1.3 多行数据指定列插入 📕2. Retrieve 检索✏️2.1 全列查询✏️2.2 指定列查询✏️2.3 查询字段为表达式✏️2.4 为查询结果指定别名✏️2.5 结果去重查询 …...
08_双向循环神经网络
双向网络 概念 双向循环神经网络(Bidirectional Recurrent Neural Network, BiRNN)通过同时捕捉序列的正向和反向依赖关系,增强模型对上下文的理解能力。与传统的单向网络不同,BIRNN 能够同时从过去和未来的上下文信息中学习,从而提升模型的…...
JSON数据修改的实现
JSON数据的修改 示例代码如下: using System.Collections; using System.Collections.Generic; using UnityEngine; //C#命名空间(以System开头) using System.IO; using LitJson; public class JsonChange : MonoBehaviour {// Start is called befor…...
2025年Postman的五大替代工具
虽然Postman是一个广泛使用的API测试工具,但许多用户在使用过程中会遇到各种限制和不便。因此,可能需要探索替代解决方案。本文介绍了10款强大的替代工具,它们能够有效替代Postman,成为你API测试工具箱的一部分。 什么是Postman&…...
(四)---四元数的基础知识-(定义)-(乘法)-(逆)-(退化到二维复平面)-(四元数乘法的导数)
使用四元数的原因 最重要的原因是因为传感器的角速度计得到的是三个轴的角速度, 这三个轴的角速度合成一个角速度矢量, 结果就是在微小时间内绕着这个角速度矢量方向为轴旋转一定角度. 截图来源网址四元数 | Crazepony开源四轴飞行器...
汇能感知高品质的多光谱相机VSC02UA
VSC02UA概要 VSC02UA是一款高品质的200万像素的光谱相机,适用于工业检测、农业、医疗等领域。VSC02UA 包含 1600 行1200 列有源像素阵列、片上 10 位 ADC 和图像信号处理器。它带有 USB2.0 接口,配合专门的电脑上位机软件使用,可进行图像采集…...
【SpringBoot】MorningBox小程序的完整后端接口文档
以下是「晨光宅配」小程序的完整接口文档,涵盖了所有12个表的接口。 每个接口包括请求方法、URL、请求参数、响应格式和示例 接口文档 1. 用户模块 1.1 获取用户信息 URL: /user/{userId}方法: GET请求参数: userId (路径参数): 用户ID响应格式:{"userId": 1,&qu…...
Blazor+PWA技术打造全平台音乐播放器-从音频缓存到离线播放的实践之路
开局三张图… 0.起源 主要是自己现在用的是苹果手机,虽然手机很高级,但是想听自己喜欢的歌曲确是不容易,在线app都要付费,免费的本地播放器都不太好用(收费的也不太行),基础功能都不满足。此外…...
使用LangChain开发智能问答系统
代码地址见文末 1. 项目配置 1.1 Neo4j 数据库配置 1. 安装与环境变量 解压路径:将neo4j-community-5.x.x.zip解压至D:\neo4j-community-5.x.x环境变量: NEO4J_HOME: D:\neo4j-community-5.x.xJAVA_HOME: D:\neo4j-community-5.x.x\jdk(注意:需指向 JDK 目录)Path 变量…...
Centos操作系统安装及优化
Centos操作系统安装及优化 零、环境概述 主机名 centos版本 cpu 内存 Vmware版本 ip地址 test CentOS Linux release 7.6.1810 (Core) 2C 2G 15.5.1 10.0.0.10 一、介质下载 1、7.6版本下载 CentOS7.6标准版下载链接: https://archive.kernel.org/centos-vault/7.6.1810/i…...
游戏引擎学习第177天
仓库:https://gitee.com/mrxiao_com/2d_game_4 今日计划 调试代码有时可能会非常困难,尤其是在面对那些难以发现的 bug 时。显然,调试工具是其中一个非常重要的工具,但在游戏开发中,另一个非常常见的工具就是自定义的调试工具&a…...
springCloud集成tdengine(原生和mapper方式) 其一
第一种 mapper方式,原生方式在主页看第二章 一、添加pom文件 <!-- HikariCP 连接池 --><dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId></dependency><!-- TDengine 连接器--><de…...
数据结构知识点1
目录 一、时间复杂度和空间复杂度 1.1时间复杂度: 1.2空间复杂度: 二、装箱和拆箱 三、泛型 3.1泛型类的使用: 3.2泛型的上界: 3.3泛型方法: 一、时间复杂度和空间复杂度 1.1时间复杂度: 时间复杂…...
时序数据库QuestDB在Winform窗体应用
以下是QuestDB在Winform使用的代码: //初始化 private void Init() { //创建数据库对象 (用法和EF Dappper一样通过new保证线程安全) SqlSugarClient Db new SqlSugarClient(new ConnectionConfig() { ConnectionString “host10.3.5.227;port8812;usernameadmin;…...
从零开始学习 Go 语言
Go 语言(又称 Golang)是由 Google 开发的一种静态强类型、编译型、并发型编程语言。它以其简洁的语法、高效的并发支持和强大的标准库而闻名,非常适合开发高性能的服务器端应用、分布式系统和云计算工具。本文将从零开始,详细介绍…...
自由学习记录(45)
顶点片元着色器(important) 1.需要在Pass渲染通道中编写着色器逻辑 2.可以使用cG或HLSL两种shader语言去编写Shader逻辑 3.代码量较多,灵活性较强,性能消耗更可控,可以实现更多渲染细节 4.适用于光照处理较少…...
数据源支持远程Excel/CSV,数据集支持分组字段功能,DataEase开源BI工具v2.10.6 LTS版本发布
2025年3月17日,人人可用的开源BI工具DataEase正式发布v2.10.6 LTS版本。 这一版本的功能变动包括:数据源方面,新增支持远程Excel/CSV数据源,支持以HTTP、HTTPS、FTP协议获取远程服务器上的Excel和CSV数据文件,并且可以…...
