当前位置: 首页 > article >正文

二维前缀和:高效求解矩阵区域和问题

在处理二维矩阵时,频繁计算某一子矩阵的和是一个常见的操作。传统的做法是直接遍历该子矩阵,时间复杂度较高。当矩阵非常大且有大量的查询时,直接计算将变得低效。为了提高效率,我们可以通过 二维前缀和 技巧在常数时间内解决这个问题。

本文将通过一个具体的 Java 实现,介绍如何使用二维前缀和优化子矩阵求和问题。

关键是二维前缀和数组的构造,以及求解区域和的代码部分

测试链接:https://leetcode.cn/problems/range-sum-query-2d-immutable/

一、前缀和的概念

前缀和是解决区间和问题的经典技巧。在一维数组中,前缀和数组 prefixSum 用于存储从数组开头到当前位置的累加和,这样我们可以在 O(1) 时间内查询任意区间 [l, r] 的和。

二维前缀和的思想类似,它在二维矩阵上扩展了前缀和的概念。给定一个 m x n 的矩阵 matrix,二维前缀和数组 sum 中的元素 sum[i][j] 表示从左上角 (0, 0)(i-1, j-1) 的所有矩阵元素的和。通过构造这个前缀和数组,我们能够在常数时间内查询任意子矩阵的元素和。

二、二维前缀和的计算

2.1 二维前缀和的构建

对于一个 m x n 的矩阵 matrix,我们定义一个同样大小的前缀和数组 sum,其中 sum[i][j] 表示从 (0, 0)(i-1, j-1) 的矩阵元素和。构造 sum[i][j] 的公式如下:

sum[i][j] = matrix[i-1][j-1] + sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1]
  • matrix[i-1][j-1]:当前矩阵元素。
  • sum[i-1][j]:上方区域的和。
  • sum[i][j-1]:左侧区域的和。
  • sum[i-1][j-1]:左上角区域重复计算的部分,需要减去。

这样通过累加计算每个位置的前缀和,最终可以在常数时间内求出任意子矩阵的和。

2.2 子矩阵和的查询

通过上述方式构造的二维前缀和数组,可以快速计算任意子矩阵的元素和。给定一个矩阵区域的左上角 (row1, col1) 和右下角 (row2, col2),其和可以通过以下公式计算:

sumRegion(row1, col1, row2, col2) = sum[row2+1][col2+1]- sum[row1][col2+1]- sum[row2+1][col1]+ sum[row1][col1]

三、Java 实现

以下是使用二维前缀和优化矩阵区域和查询的 Java 实现。我们将使用 NumMatrix 类来实现:

public class NumMatrix {private int[][] sum;// 构造函数:计算二维前缀和public NumMatrix(int[][] matrix) {int n = matrix.length;int m = matrix[0].length;sum = new int[n + 1][m + 1];  // 创建一个多出一行一列的前缀和数组// 填充前缀和数组for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {sum[i][j] = matrix[i - 1][j - 1] + sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1];}}}// 查询子矩阵的和public int sumRegion(int row1, int col1, int row2, int col2) {row1++;col1++;row2++;col2++;return sum[row2][col2] - sum[row1 - 1][col2] - sum[row2][col1 - 1] + sum[row1 - 1][col1 - 1];}public static void main(String[] args) {// 示例矩阵int[][] matrix = {{3, 2, 1, 4},{1, 5, 3, 2},{4, 2, 2, 1},{7, 4, 3, 5}};// 创建 NumMatrix 对象NumMatrix numMatrix = new NumMatrix(matrix);// 查询子矩阵 (1,1) 到 (2,2) 的和System.out.println(numMatrix.sumRegion(1, 1, 2, 2));  // 输出:15}
}
3.1 代码分析
  1. 构造函数NumMatrix(int[][] matrix) 用来构造二维前缀和数组 sum。首先,构造一个大小为 (n+1) x (m+1) 的数组,额外的行和列用于处理边界问题。然后通过双重循环填充 sum 数组,利用之前的公式逐步计算前缀和。

  2. sumRegion 方法sumRegion(int row1, int col1, int row2, int col2) 用于查询子矩阵 (row1, col1)(row2, col2) 的和。通过前缀和的计算公式,能够在常数时间内返回结果。

  3. 主函数:在 main 方法中,我们定义了一个 matrix,并创建了 NumMatrix 对象来处理前缀和的计算。然后调用 sumRegion 方法查询从 (1,1)(2,2) 的子矩阵和,输出为 15

四、时间复杂度

  • 前缀和数组的构造:构造二维前缀和数组的时间复杂度是 O(m * n),其中 mn 分别是矩阵的行数和列数。
  • 查询子矩阵和:查询的时间复杂度是 O(1),因为我们只需要做常数次的数组访问和加减操作。

五、应用场景

二维前缀和特别适用于以下场景:

  1. 静态矩阵区域求和:如果我们需要对矩阵中多个子矩阵进行求和,二维前缀和能够显著减少查询时间。
  2. 优化算法中的区间求和:在一些动态规划或分治算法中,二维前缀和可以高效地处理二维区间和查询。

相关文章:

二维前缀和:高效求解矩阵区域和问题

在处理二维矩阵时&#xff0c;频繁计算某一子矩阵的和是一个常见的操作。传统的做法是直接遍历该子矩阵&#xff0c;时间复杂度较高。当矩阵非常大且有大量的查询时&#xff0c;直接计算将变得低效。为了提高效率&#xff0c;我们可以通过 二维前缀和 技巧在常数时间内解决这个…...

音视频入门基础:RTP专题(5)——FFmpeg源码中,解析SDP的实现

一、引言 FFmpeg源码中通过ff_sdp_parse函数解析SDP。该函数定义在libavformat/rtsp.c中&#xff1a; int ff_sdp_parse(AVFormatContext *s, const char *content) {const char *p;int letter, i;char buf[SDP_MAX_SIZE], *q;SDPParseState sdp_parse_state { { 0 } }, *s1…...

Android开发工作经历整理

一.无人机应用软件开发 集成大疆官网的DJIMobileSDK到AS中编写软件&#xff0c;操控无人机执行多个航点任务。集成OpenCV库进行图像识别&#xff0c;通过获取参数&#xff0c;根据算法执行sdk&#xff0c;使无人机降落到机库&#xff0c;并执行后续的换电操作。待无人机就绪后…...

C++中常用的十大排序方法之4——希尔排序

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C中常用的排序方法之4——希尔排序的相…...

解决注入线程池的栈溢出问题

文章目录 1.问题产生2.问题解决 1.问题产生 在使用sleuth的时候&#xff0c;需要注入线程池&#xff0c;他才会自动包装&#xff0c;实现traceId的传递&#xff0c;但是突然启动时出现了栈溢出的问题 2.问题解决 根据报错&#xff0c;发现是Gson序列化相关的问题&#xff0c…...

自动驾驶---两轮自行车的自主导航

1 背景 无人驾驶汽车最早出现在DARPA的比赛中&#xff0c;从那个时刻开始&#xff0c;逐渐引起全球学者的注意&#xff0c;于是从上个世纪开始各大高校院所开始了无人汽车的研发。直到这两年&#xff0c;无人驾驶汽车才开始走进寻常百姓家&#xff0c;虽然目前市面上的乘用车还…...

哈夫曼树并查集

&#xff08;1&#xff09;哈夫曼树 特殊概念&#xff1a; 1.结点的权&#xff1a;表示结点树的重要性 2.带权路径长度&#xff1a;从树的根到该节点的路径长度&#xff08;经过的边数&#xff09;与该节点上权值的乘积 2.树的带权路径长度&#xff1a;该树的所有叶子节点的…...

PyTorch数据建模

回归分析 import torch import numpy as np import pandas as pd from torch.utils.data import DataLoader,TensorDataset import time strat = time.perf_counter()...

在 Ubuntu 上安装 Node.js 23.x

在 Ubuntu 上安装 Node.js 23.x 前提条件安装步骤1. 下载设置脚本2. 运行设置脚本3. 安装 Node.js4. 验证安装 参考链接总结 在现代 web 开发中&#xff0c;Node.js 是一个不可或缺的工具。它提供了一个强大的 JavaScript 运行时环境&#xff0c;使得开发人员可以在服务器端使用…...

SQL范式与反范式_优化数据库性能

1. 引言 什么是SQL范式 SQL范式是指数据库设计中的一系列规则和标准,旨在减少数据冗余、提高数据完整性和一致性。常见的范式包括第一范式(1NF)、第二范式(2NF)、第三范式(3NF)和BCNF(Boyce-Codd范式)。 什么是SQL反范式 SQL反范式是指在满足范式要求的基础上,有…...

hunyuan 混元学习

使用了5个subset,也是用了text-image和text-video进行训练的 也是进行了复杂的视频选择。同movie gen. 也进行了模型切断&#xff0c;用拉普拉斯算子找到最清晰的一帧作为训练的起始 训练了不同的模型去选择数据&#xff0c;比如用Dover去选择美观度比较好的数据&#xff0c…...

四、GPIO中断实现按键功能

4.1 GPIO简介 输入输出&#xff08;I/O&#xff09;是一个非常重要的概念。I/O泛指所有类型的输入输出端口&#xff0c;包括单向的端口如逻辑门电路的输入输出管脚和双向的GPIO端口。而GPIO&#xff08;General-Purpose Input/Output&#xff09;则是一个常见的术语&#xff0c…...

.Net / C# 繁体中文 与 简体中文 互相转换, 支持地方特色词汇

版本号 Nuget 搜索 “OpenCCNET”, 注意别找错, 好多库的名字都差不多 支持 “繁,简” 的互相转换, 支持多个地区常用词汇的转换, 还支持 日文的新旧转换. OpenCC 在 .Net 中的实现 https://github.com/CosineG/OpenCC.NET <PackageReference Include"OpenCCNET"…...

一元函数微积分的几何应用:二维平面光滑曲线的曲率公式

文章目录 前言曲率和曲率半径的定义曲率计算公式参数方程形式直角坐标显式方程形式极坐标形式向量形式 前言 本文将介绍二维平面光滑曲线的曲率定义以及不同形式的曲率及曲率半径公式的推导。 曲率和曲率半径的定义 &#xff08;关于二维平面光滑曲线的定义以及弧长公式请参…...

数据结构与算法之异步: LeetCode 1114. 按序打印 (Ts版)

按序打印 https://leetcode.cn/problems/print-in-order/description/ 描述 给你一个类&#xff1a; public class Foo {public void first() { print("first"); }public void second() { print("second"); }public void third() { print("third&qu…...

python:求解爱因斯坦场方程

在物理学中&#xff0c;爱因斯坦的广义相对论&#xff08;General Relativity&#xff09;是描述引力如何作用于时空的理论。广义相对论由爱因斯坦在1915年提出&#xff0c;并被阿尔伯特爱因斯坦、纳森罗森和纳尔逊曼德尔斯塔姆共同发展。广义相对论的核心方程是爱因斯坦场方程…...

PostgreSQL 数据备份与恢复:掌握 pg_dump 和 pg_restore 的最佳实践

title: PostgreSQL 数据备份与恢复:掌握 pg_dump 和 pg_restore 的最佳实践 date: 2025/1/28 updated: 2025/1/28 author: cmdragon excerpt: 在数据库管理中,备份与恢复是确保数据安全和业务连续性的关键措施。PostgreSQL 提供了一系列工具,以便于数据库管理员对数据进行…...

位运算的概念

文章目录 整数在计算机中的表示二进制表示有符号类型和无符号类型机器数和真值原码、反码和补码原码、反码和补码的表示方法计算机中的表示 位运算与、或、异或和取反移位运算移位运算与乘除法的关系位运算的性质 目录 整数在计算机中的表示 二进制表示 程序中的所有数在计算…...

自主Shell命令行解释器

什么是命令行 我们一直使用的"ls","cd","pwd","mkdir"等命令&#xff0c;都是在命令行上输入的&#xff0c;我们之前对于命令行的理解&#xff1a; 命令行是干啥的&#xff1f;是为我们做命令行解释的。 命令行这个东西实际上是我们…...

Vue.js 的介绍与组件开发初步

Vue.js 的介绍与组件开发初步 Vue.js 的介绍与组件开发初步引言第一部分&#xff1a;Vue.js 基础入门1.1 什么是 Vue.js&#xff1f;1.2 搭建 Vue.js 开发环境安装 Node.js 和 npm安装 Vue CLI创建新项目运行示例 1.3 第一个 Vue.js 示例 第二部分&#xff1a;Vue.js 组件开发基…...

XCCL、NCCL、HCCL通信库

XCCL提供的基本能力 XCCL提供的基本能力 不同的XCCL 针对不同的网络拓扑&#xff0c;实现的是不同的优化算法的&#xff08;不同CCL库最大的区别就是这&#xff09; 不同CCL库还会根据自己的硬件、系统&#xff0c;在底层上面对一些相对应的改动&#xff1b; 但是对上的API接口…...

Python教学:文档处理及箱线图等

代码1&#xff1a; import os import pandas as pd import numpy as py import os.path from os import listdir import openpyxl from openpyxl import Workbook import re import matplotlib.pyplot as plt # 导入matplotlib的绘图模块&#xff0c;用于可视化 cwdos.getcwd…...

【Redis】安装配置Redis超详细教程 / Linux版

Linux安装配置Redis超详细教程 安装redis依赖安装redis启动redis停止redisredis.conf常见配置设置redis为后台启动修改redis监听地址设置工作目录修改密码监听的端口号数据库数量设置redis最大内存设置日志文件设置redis开机自动启动 学习视频&#xff1a;黑马程序员Redis入门到…...

【大数据技术】教程05:本机DataGrip远程连接虚拟机MySQL/Hive

本机DataGrip远程连接虚拟机MySQL/Hive datagrip-2024.3.4VMware Workstation Pro 16CentOS-Stream-10-latest-x86_64-dvd1.iso写在前面 本文主要介绍如何使用本机的DataGrip连接虚拟机的MySQL数据库和Hive数据库,提高编程效率。 安装DataGrip 请按照以下步骤安装DataGrip软…...

springboot 启动原理

目标&#xff1a; SpringBootApplication注解认识了解SpringBoot的启动流程 了解SpringFactoriesLoader对META-INF/spring.factories的反射加载认识AutoConfigurationImportSelector这个ImportSelector starter的认识和使用 目录 SpringBoot 启动原理SpringBootApplication 注…...

llama.cpp GGUF 模型格式

llama.cpp GGUF 模型格式 1. Specification1.1. GGUF Naming Convention (命名规则)1.1.1. Validating Above Naming Convention 1.2. File Structure 2. Standardized key-value pairs2.1. General2.1.1. Required2.1.2. General metadata2.1.3. Source metadata 2.2. LLM2.2.…...

使用Pytorch训练一个图像分类器

一、准备数据集 一般来说&#xff0c;当你不得不与图像、文本或者视频资料打交道时&#xff0c;会选择使用python的标准库将原始数据加载转化成numpy数组&#xff0c;甚至可以继续转换成torch.*Tensor。 对图片而言&#xff0c;可以使用Pillow库和OpenCV库对视频而言&#xf…...

PythonStyle MVC 开发框架

在 Python 中&#xff0c;MVC&#xff08;Model - View - Controller&#xff0c;模型 - 视图 - 控制器&#xff09;是一种常见的软件设计模式&#xff0c;它将应用程序分为三个主要部分&#xff0c;各自承担不同的职责&#xff0c;以提高代码的可维护性、可扩展性和可测试性。…...

HTTP协议的无状态和无连接

无连接 ①无连接的含义 这里所说的无连接并不是指不连接&#xff0c;客户与服务器之间的HTTP连接是一种一次性连接&#xff0c;它限制每次连接只处理一个请求&#xff0c;当服务器返回本次请求的应答后便立即关闭连接&#xff0c;下次请求再重新建立连接。这种一次性连接主要考…...

毫秒级响应的VoIP中的系统组合推荐

在高并发、低延迟、毫秒级响应的 VoIP 场景中&#xff0c;选择合适的操作系统组合至关重要。以下是针对 Ubuntu linux-lowlatency、CentOS Stream kernel-rt 和 Debian 自定义 PREEMPT_RT 的详细对比及推荐&#xff1a; 1. 系统组合对比 特性Ubuntu linux-lowlatencyCentO…...