前缀和数组

数组中的前缀和 前缀和指一个数组的某下标之前的所有元素的和(包含其本身)。前缀和分为一维前缀和,以及二维前缀和。前缀和是一种重要的预处理方式,能够降低算法的时间复杂度。看完这道题,我们可能首先想到的是遍历数组。 题目要求我们实现这样一个类 sumRange函数返回一个索引区间的和 这样写可以到到效果,但是效率会很差,因为sumRange方法会被频繁调用,而他的复杂度是O(N),其中N代表nums数组的长度。这道题的最优解法是使用前缀和技巧,将sumRange函数的时间复杂度将为O(1),就是不要在函数中使用for循环。 如 阅读详情

前言

    本文是基于labuladong算法秘籍的学习总结,是算法总结中的数组与链表篇章,其他篇章以及资料下载在算法学习总结目录中下载,传送门:算法学习总结
  本人是算法菜鸟一枚,通过在学习过程中总结来提升自我,共同进步,有理解不当的地方欢迎大家指正!

一、前缀和理解

前缀和技巧适⽤于快速、频繁地计算⼀个索引区间内的元素之和。前缀和可用于一维及多维数组。

二、原理与代码

2.1 一维数组的前缀和

以典型例题为例,展示一维数组前缀和的构造思路:
给定一个整数数组 nums,求出数组从索引 i 到 j(i ≤ j)范围内元素的总和,包含 i、j两点。
在这里插入图片描述

 class NumArray {
	    private int[] preSum;
	    public NumArray(int[] nums) {
	        preSum = new int[nums.length+1];
	        // preSum[0] = 0; 便于累加
	        for(int i = 1;i<preSum.length;i++){
	            preSum[i] = preSum[i-1]+nums[i-1];
	        }
	    }
    
	    public int sumRange(int left, int right) {
	        return preSum[right+1]-preSum[left];
	    }
    }	

值得注意地方有以下几点:
1、preSum前缀和数组要比原始数组的长度+1
2、构造函数中用于累加的for循环中的i在很多地方也能看到从0开始,若从0开始则如下:

        for(int i = 0;i<preSum.length;i++){
            preSum[i+1] = preSum[i]+nums[i];
        }

2.2 二维数组的前缀和

类似一维数组的前缀和思路,二维数组仅仅在构造前缀和中增加了写固定的计算的步骤,近似于在一维前缀和数组的for循环中使用了不同计算步骤,同样以典型例题讲解原理:
在这里插入图片描述
在这里插入图片描述
sumRegion([2,1,4,3])返回的元素和为8。
对于二维数组,我们同样会构造一个preSum,只是在for循环中构造的计算步骤稍区别于一维,具体计算步骤思路如下:
在这里插入图片描述
想计算红⾊的这个⼦矩阵的元素之和,可以⽤绿⾊矩阵减去蓝⾊矩阵减去橙⾊矩阵最后加上粉⾊矩阵,⽽绿蓝橙粉这四个矩阵有⼀个共同的特点,左上⻆是 (0, 0) 原点。
代码如下:

class NumMatrix {
	// preSum[i][j] 记录矩阵 [0, 0, i, j] 的元素和
	private int[][] preSum;
	public NumMatrix(int[][] matrix) {
		int m = matrix.length, n = matrix[0].length;
		if (m == 0 || n == 0) return;
		// 构造前缀和矩阵
		preSum = new int[m + 1][n + 1];
		for (int i = 1; i <= m; i++) {
			for (int j = 1; j <= n; j++) {
				// 计算每个矩阵 [0, 0, i, j] 的元素和
				preSum[i][j] = preSum[i-1][j] + preSum[i][j-1] + matrix[i- 1][j - 1] - preSum[i-1][j-1];
			}
		}
	}
	// 计算⼦矩阵 [x1, y1, x2, y2] 的元素和
	public int sumRegion(int x1, int y1, int x2, int y2) {
		// ⽬标矩阵之和由四个相邻矩阵运算获得
		return preSum[x2+1][y2+1] - preSum[x1][y2+1] - preSum[x2+1][y1] + preSum[x1][y1];
	}
}

三、典型例题

基于以上的知识可以解决Leetcode中的如下题目:
303. 区域和检索 - 数组不可变(中等)
304. ⼆维区域和检索 - 矩阵不可变(中等)
560. 和为K的⼦数组(中等)

四、补充知识

这里将对本节中涉及的一些基础知识做一些补充和拓展

1、构造函数

在前缀和的算法题中,题目经常会要求我们实现一个前缀和的类,这个类将被如下方式调用:

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray obj = new NumArray(nums);
 * int param_1 = obj.sumRange(left,right);
 */

因此,要记得实现一个有参构造函数,因此在此拓展一下构造函数的相关知识:
1)每个方法必然有一个构造方法,有参或无参,若没有提供有参,则会自动构造一个无参。
2)创建一个子类对象的实例的时候,必先调用父类的无参构造函数(默认构造函数),除非子类显示指定super。若父类的无参为private或在有有参情况下,没有显示定义无参,或者子类没有显示指定继承父类构造方法,编译会报错。
因此,解决方法一般是,在子类super指定,或者在父类显示添加无参构造方法。

2、修饰符范围

上面的构造函数中提到了修饰符,因此,补充一下修饰符的基础。
在这里插入图片描述
还有final、和abstract修饰符:
final修饰的类不能被继承,没有子类。
abstract修饰的类不能被实例化,必须被子类继承。类只要有一个抽象方法就必定是抽象类,但抽象类不一定要有抽象方法。

3、二维数组

二维数组可以理解为是一维数组,只不过他的各处的元素是特殊元素—–一维数组
a[0][0] a[0][1] a[0][2] a[0][3]
a[1][0] a[1][1] a[1][2] a[1][3]
a[2][0] a[2][1] a[2][2] a[2][3]

//定义一个整型数组:3行4列int a[][] = new int[3][4];
//获取行数---3行int lenY = a.length;
//获取列数---4列int lenX = a[0].length;
二维数组前缀和图解 二维前缀和s[i][j]表示从二维数组的左上角(1, 1)到(i, j)的所有元素的和。它的计算公式为:s[i-1][j]是上方的前缀和。s[i][j-1]是左方的前缀和。是左上方的前缀和(因为被重复计算了,需要减去)。a[i][j]是当前元素的值。 阅读详情

相关推荐

程序员的自我修养

一个好的程序员的自我修养需要从不同角度出发,工作能力是一个方面,对自身的定位和了解也是一个方面,程序员的工作能力修养包括需求理解、功能设计、沟通确认、代码规范、成果验证、代码重构优化等,通过自我剖析来对自身进行定位并了解自身的优缺点,如去除劣根性、端正意识形态与态度、提升自己的核心竞争力等。 自我剖析 一个成功的人,必须要先了解自己,只有了解自己是什么样的人,了解自身有哪些优缺点,了解自己更合适做什么工作,知道自己做什么才能发挥出自身的优势,这样才能使自己在工作中发光发热,在职业生涯的道路上走的更远。

数通畅联 1672

基本数据结构---前缀和数组

文章目录前言一、应用场景?二、模板三、实践1.303. 区域和检索 - 数组不可变2、304. 二维区域和检索 - 矩阵不可变3、560. 和为 K 的子数组总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下面案例可供参考 一、应用场景? 前缀和主要适用的场景是原始数组不会被修改的情况下,频繁查询某个区间的累加和.prefix[i+1] 就代表着

weixin_44484668的博客 830

OLLAMA_HOST环境变量设置全攻略:从127.0.0.1到局域网共享的完整配置

本文详细解析了OLLAMA_HOST环境变量的核心作用与配置方法,指导用户如何将Ollama服务从仅限本机访问(127.0.0.1)扩展到局域网共享。文章涵盖了macOS、Linux、Windows三大平台的实战配置步骤,并提供了安全加固、性能优化及常见故障排查方案,是解决多设备协作访问本地AI模型的完整指南。

weixin_28455801的博客 1893

前缀和算法

了解前缀和算法以及相关模板例题

m0_75006599的博客 1380

保姆级教程:在RK3568开发板上手把手配置RMII百兆以太网DTS节点

本文提供了一份详细的RK3568开发板RMII百兆以太网DTS节点配置教程,涵盖基础概念解析、关键参数设置、实际操作步骤及常见问题排查。通过手把手指导,帮助开发者快速完成RK3568开发板的以太网配置,特别适合嵌入式系统开发者参考。

weixin_33686714的博客 136

python解析通达信dat与blk数据文件【附源码】

本文介绍了一个完整的通达信金融数据解析器项目,该项目攻克了通达信专有二进制文件格式解析的技术难题。项目采用模块化架构,从基础二进制解析到增强数据分类,最终实现智能语义化列名生成,形成完整的数据处理链路。核心技术包括自适应编码检测、智能数据类型推断和基于业务规则的语义化处理,解决了逆向工程、多编码兼容性等挑战。项目成果显著,解析成功率达100%,数据可读性大幅提升,开发效率提高50%,为量化交易、可视化分析等场景提供了可靠数据支持。该方案不仅具备技术创新性,更具有实际工程应用价值,为金融数据分析领域提供了可复

qq_36224726的博客 2687

前缀和数组(算法)

如何快速求得一个数组的前缀和?

2301_81831423的博客 4247

【保姆级教程】基于UNet++&MobileNetv3的语义分割模型从训练到RK3588部署:让边缘AI落地效率提升300%

通过SMP库一键构建encoder_name="mobilenet_v2", # 选择MobileNetv3作为骨干encoder_weights="imagenet", # 加载预训练权重加速收敛in_channels=3, # 输入图像通道数(RGB)classes=29, # Cityscapes数据集类别数activation=None # 输出无激活,便于后续损失计算本教程从“模型设计-训练-转换-边缘部署”全链路拆解了。

FJN110的博客 252

前缀和——(2)二维数组前缀和

前面部分我们介绍了一维前缀和https://blog.youkuaiyun.com/justidle/article/details/103524440。下面我们扩展一下,来介绍二维前缀和。 什么是二维前缀和 比如我们有这样一个矩阵a,如下所示: 1 2 4 3 5 1 2 4 6 3 5 9 我们定义一个矩阵sum,其中,那么这个矩阵就是这样的: 1 3 7 10 6 9 15 22...

努力中的老周的专栏 2万+

使用 MATLAB/Simulink + Simscape Electrical + Simulink Design Optimization,构建一个沙漠环境中光伏组件灰尘积累与效率下降仿真模型

本文通过,构建了沙漠环境中光伏组件灰尘积累与效率下降仿真模型✅ 建立了风速-沙尘-积尘速率的物理关系✅ 仿真了灰尘积累过程及其对Isc 和 Pmax的影响✅ 量化分析了不同清洁策略的经济性✅ 提出了优化设计与智能运维建议。

xiaoheshang_123的博客 121

链路状态路由协议 OSPF (一)

本章将会学习链路状态路由协议OSPF,理解OSPF的基本概念,工作原理,掌握OSPF配置基本命令。本章重点,OSPF的基本概念,OSPF配置。

yj11290301的博客 3473

C++ 前缀和数组

前缀和算法通过预处理数组,计算从起始位置到每个位置的和,生成一个新的数组(前缀和数组)。利用该数组,可以快速计算任意区间的和,快速求出数组中某一段连续区间的和。

2401_83185143的博客 1414

AI测试干货:Claude Code Skill 从入门到精通

本文介绍了Claude Code Skill功能如何解决AI重复工作问题。传统提示词方式需要人工复制粘贴,而Skill功能通过建立AI工作记忆库实现智能触发和分层加载。Skill包含工作指令、文档和资源,能自动执行任务。文章以API测试用例生成为例,展示了Skill的创建流程和结构化设计,包括测试框架、覆盖场景和输出格式,显著提升测试工程师的工作效率。

blues_C的博客 2434

【一本通】动态数组,计算前缀和数组

b是数组a的前缀和的数组定义:b[i]=a[1]+a[2]+…+a[i],即 b[i]是a的i个元素的和。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 4552

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

【CSP考点回顾】前缀和数组

前缀和算法是一种用于处理数组的技术,它可以快速计算任何。适合在。使用前缀和算法可以将每次求和的时间复杂度从 O(n) 降低到 O(1)。ArrpreArriArr0...i−1那么,求索引区间14内所有元素之和,可以通过preArr5−preArr1得出。这样,便只需要做一次减法运算,避免了每次进行 for 循环调用,时间复杂度为常数O1。前缀和算法广泛用于处理数组求和问题,特别是当,它可以大大减少计算时间。

fzy2003的博客 1282

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

二维数组前缀和

二维数组前缀和 对于二维数组求前缀和,我们先预处理第一行跟第一列的前缀和 第一行跟第一列的前缀和可以看作一维数组的前缀和 前缀和数组的0,0等于原数组的0,0,第一行为原数组第一行的前缀和,第一列为第一列的前缀和 预处理: //原数组 int arr[10][10]={ {1,2,3,4,5,6,7,8,9,0}, {6,7,8,9,0,1,2,3,4,5}, {1,2,3,4,5,6,7,8,9,0}, {1

aaaghyaa的博客 2809

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

数组前缀和算法技巧

数组中前缀和技巧(Prefix Sum Technique)是一种常见且有用的算法技巧,特别适用于需要频繁查询数组区间和的问题。这种技巧通过创建一个额外的数组来存储原始数组中特定位置之前所有元素的和,从而在需要计算任意子数组和时能够快速得出结果;前缀和技巧的优点在于它可以将原先需要O(n)时间复杂度计算的区间和问题,转化为O(1)时间复杂度的查询操作。这在某些问题中可以大大提高算法的效率。

Zach的博客 1512

数组之前缀和

数组前缀和一图解

一枚数学专业的小码农的博客 665

[算法]二维数组前缀和

今天在学校oj平台做题时,有一道题目老是时间超限,后询问学长得知需要算法减少时间开销,于是习得了一个快速计算给定一个二维数组,求子数组的数组和,即二维前缀和。这样的好处是: 大大减少了原先通过两层for循环计算子数组所耗费的时间,只需要在插入数据时,对应的计算出二维前缀和数组,计算子矩阵的元素之和时不需要双层遍历,直接通过公式计算而的,这极大的减少了时间复杂度。输入一个 n 行 m 列的整数矩阵,再输入 q 个询问,每个询问包含四个整数 x1,y1,x2,y2,表示一个子矩阵的左上角坐标和右下角坐标。

Belldrea的博客 3315

通用算法 - [数组算法] -数组的前缀和

1、前缀和介绍 对于一个数组AAA,我们新建一个长度相等的数组BBB,新数组中的每一项B[i]B[i]B[i]表示的是数组AAA的前iii项和,即 前缀和:BBB中的每一项B[i]B[i]B[i]保存A[0,1,...,i]A[0,1,...,i]A[0,1,...,i]的和; 类似的概念还有: 后缀和:BBB中的每一项B[i]B[i]B[i]保存A[i,i+1,...,n−1]A[i,i+1,....

Olivaf的博客 1471

数组前缀和

在这一道题目里面,中间某一段连续子数组和为k,意思即为sum[i] - sum[j - 1] = k,也即sum[i] - k = sum[j - 1],所以当我们求每一个的前缀和的时候,只需要统计对应的sum[j - 1]个数即可。前缀和就是指前缀的和,例如在数组中,从开始到 i 就是到 i 的前缀和。前缀和一般用来求中间连续某一段的和,例如sum[i] - sum[j - 1]就可以求出j 到 i 这一段的和。当然还有二维数组的前缀和,不过大致原理就是这样,通过两个前缀和求中间的和。

qq_46514141的博客 861

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

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

SnowK博客 2898

【前缀和】连续数组

​ 给定一个二进制数组nums, 找到含有相同数量的0和1的最长连续子数组,并返回该子数组的长度。01。

lirendada的博客 978

返回数组的前缀和

给一个数组 nums 。 数组「前缀和」的计算公式为: rtSum[i] = sum(nums[0]…nums[i]) 。 请返回 nums 的前缀和 算法思想: 1.读入一个数组——通过循环改变数组下标,按照下标从小到大依次输入数据 for (int i = 0; i < sizeof(nums) / sizeof(int); i++) { scanf_s("%d", &nums[i]); if (nums[i] == -1) break; } 2.rtSum数组的每一项

weixin_46465145的博客 260
上一篇: 算法学习目录
下一篇: Java中的常用队列
Archie敲键盘
博客等级 码龄7年 9粉丝 25原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值