面试算法13:二维子矩阵的数字之和

题目

输入一个二维矩阵,如何计算给定左上角坐标和右下角坐标的子矩阵的数字之和?对于同一个二维矩阵,计算子矩阵的数字之和的函数可能由于输入不同的坐标而被反复调用多次。例如,输入图2.1中的二维矩阵,以及左上角坐标为(2,1)和右下角坐标为(4,3)的子矩阵,该函数输出8。
在这里插入图片描述

分析

如果不考虑时间复杂度,则采用蛮力法用两个嵌套的循环总是可以求出一个二维矩阵的数字之和。如果矩阵的行数和列数分别是m和n,那么这种蛮力法的时间复杂度是O(mn)。

只是这个题目提到,对于一个二维矩阵,可能由于输入不同的坐标而反复求不同子矩阵的数字之和,这说明应该优化求和的过程,要尽可能快地实现子矩阵的数字求和。
在这里插入图片描述
阴影面积 = 黄色正方形面积 + 绿色正方行面积 - 红色长方形面积 - 蓝色长方形面积

因此,可以在预处理阶段求出从左上角坐标为(0,0)到每个右下角坐标的子矩阵的数字之和。首先创建一个和输入矩阵大小相同的辅助矩阵sums,该矩阵中的坐标(i,j)的数值为输入矩阵中从左上角坐标(0,0)到右下角坐标(i,j)的子矩阵的数字之和。

下面分析如何生成辅助矩阵sums,即求得数组中的每个数字sums[i][j]。按照生成辅助矩阵sums的规则,sums[i][j]的值等于输入矩阵中从左上角坐标为(0,0)到右下角坐标为(i,j)的子矩阵的数字之和。可以把从左上角坐标为(0,0)到右下角坐标为(i,j)的子矩阵的数字看成由两部分组成。第1部分是从左上角坐标为(0,0)到右下角坐标为(i-1,j)的子矩阵,该子矩阵的数字之和等于sums[i-1][j]。第2部分是输入矩阵中第i行中列号从0到j的所有数字。如果按照从左到右的顺序计算sums[i][j],则可以逐个累加第i行的数字,从而得到子矩阵第2部分的数字之和。

public class Test {public static void main(String[] args) {int[][] nums = {{3, 0, 1, 4, 2},{5, 6, 3, 2, 1},{1, 2, 0, 1, 5},{4, 1, 0, 1, 7},{1, 0, 3, 0, 5}};sums = generateNumMatrix(nums);int result = sumRegion(2, 1, 4, 3);System.out.println(result);}private static int[][] sums;public static int[][] generateNumMatrix(int[][] matrix) {if (matrix.length == 0 || matrix[0].length == 0) {return null;}int[][] sums = new int[matrix.length + 1][matrix[0].length + 1];for (int i = 0; i < matrix.length; i++) {int rowSum = 0;for (int j = 0; j < matrix[0].length; j++) {rowSum += matrix[i][j];sums[i + 1][j + 1] = sums[i][j + 1] + rowSum;}}return sums;}public static int sumRegion(int row1, int col1, int row2, int col2) {//return sums[row2][col2] + sums[row1-1][col1-1] - sums[row1-1][col2] - sums[row2][col1-1];return sums[row2 + 1][col2 + 1] + sums[row1][col1] - sums[row1][col2 + 1] - sums[row2 + 1][col1];}
}

如果输入矩阵的行数和列数分别是m和n,那么辅助数组sums的行数和列数分别为m+1和n+1,这样只是为了简化代码逻辑。如果用公式sums[r2][c2]+sums[r1-1][c2]-sums[r2][c1-1]+sums[r1-1][c1-1]求解左上角坐标为(r1,c1)、右下角坐标为(r2,c2)的子矩阵的数字之和,由于坐标值r1或c1有可能等于0,因此r1-1或c1-1可能是负数,不再是有效的数组下标。如果在矩阵的最上面增加一行,最左面增加一列,这样就不必担心出现数组下标为-1的情形。

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

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

相关文章

Vue.js路由及Node.js的入门使用---超详细

一&#xff0c;Vue路由 1.1 路由是什么 路由是用来管理应用程序中不同页面之间导航的概念。Vue Router是Vue.js官方提供的路由管理器&#xff0c;它允许我们通过定义路由规则和视图组件来配置路由 1.2 路由给我们带来的好处有哪些&#xff1f; 单页应用&#xff08;Single Pag…

【深度学习实验】前馈神经网络(final):自定义鸢尾花分类前馈神经网络模型并进行训练及评价

目录 一、实验介绍 二、实验环境 1. 配置虚拟环境 2. 库版本介绍 三、实验内容 0. 导入必要的工具包 1. 构建数据集&#xff08;IrisDataset&#xff09; 2. 构建模型&#xff08;FeedForward&#xff09; a. __init__(初始化) b. forward(前向传播) 3.整合训练、评估…

2023年腾讯云服务器优惠活动整理汇总

腾讯云是腾讯集团倾力打造的云计算品牌&#xff0c;为了吸引更多的用户&#xff0c;腾讯云经常会推出各种各样的优惠活动。本文将为大家整理汇总一些腾讯云服务器的优惠活动&#xff0c;希望能够帮助到需要购买腾讯云服务器的用户。 一、腾讯云服务器优惠券 腾讯云优惠券是腾讯…

瑞云介绍使用ZBrush和Marmoset工具包制作的风格化巨怪战斗机

Renderbus瑞云渲染的小编今天给大家介绍下Gianluca Squillace使用 ZBrush 和 Marmoset 工具包制作巨怪战士的一些技巧。这位艺术家还贴心地告诉大家&#xff0c;有些步骤是可以省略跳过的&#xff0c;这样就可以节省时间&#xff0c;帮助我们快速完成角色的创作啦。快速有用的步…

云计算与大数据——Storm配置及运行WordCountTopology(保姆级教程!)

云计算与大数据——Storm配置及运行WordCountTopology&#xff08;保姆级教程&#xff01;&#xff09; 前言 当今世界正处于云计算和大数据的快速发展阶段&#xff0c;而Storm作为一种高效、可靠的实时计算框架&#xff0c;受到了广泛的关注和应用。在这篇文章中&#xff0c…

企业级磁盘阵列存储系统由硬到软全析

企业级磁盘阵列是由一组设备构成的存储系统,主要包括两种类型的设备,分别是控制器和扩展柜,其中控制器只有一台,扩展柜可以没有,也可以有多台。在EMC的Unity中分别称为DPE(Disk Processor Enclosure)和DAE(Disk Array Enclosure),在华为的OceanStor里面称为控制框和硬…

WebGL 切换着色器

目录 前言 如何实现切换着色器 1. 准备用来绘制单色立方体的着色器 2. 准备用来绘制纹理立方体的着色器 3. 调用createProgram&#xff08;&#xff09;函数&#xff0c;利用第1步创建出的着色器&#xff0c;创建着色器程序对象 4. 调用createProgram&#xff08;&…

Java 设计模式——抽象工厂模式

目录 1.概念2.结构3.实现4.优缺点5.使用场景6.模式扩展7.JDK源码解析——Collection.iterator方法 1.概念 &#xff08;1&#xff09;Java 设计模式——工厂方法模式中考虑的是一类产品的生产&#xff0c;如畜牧场只养动物、电视机厂只生产电视机等。这些工厂只生产同种类产品…

【kubernetes】【基础资源使用】kubernetes中的Deployment使用

1 Why need Deployment? K8S中Pod是用户管理工作负载的基本单位&#xff0c;Pod通常通过Service进行暴露&#xff0c;因此&#xff0c;通常需要管理一组Pod&#xff0c;RC和RS主要就实现了一组Pod的管理工作&#xff0c;其中&#xff0c;RC和RS的区别在于&#xff0c;RS提供更…

【每日一题】528. 按权重随机选择

528. 按权重随机选择 - 力扣&#xff08;LeetCode&#xff09; 给你一个 下标从 0 开始 的正整数数组 w &#xff0c;其中 w[i] 代表第 i 个下标的权重。 请你实现一个函数 pickIndex &#xff0c;它可以 随机地 从范围 [0, w.length - 1] 内&#xff08;含 0 和 w.length - 1&…

混合IT基础设施的安全挑战与缓解策略

自从“身份是新的边界”这句格言问世以来&#xff0c;公司已经开始扩展他们的能力和运营&#xff0c;超越了基于本地、办公室基础设施的范围。采用云原生技术意味着组织正在寻求扩大传统工作流程&#xff0c;而无需投入时间和资源来建立物理数据中心和其他硬件基础设施。 身份…

JTS:08 JTS图形相交

这里写目录标题 版本JTS disjoint intersects俩个图形不相交俩个图形 边相交俩个图形 内部相交俩个图形 点相交 版本 org.locationtech.jts:jts-core:1.19.0 链接: github JTS disjoint intersects 不相交的 九交模型FF*FF**** 相交的 九交模型 [T********] [*T*******] [**…

服务断路器_Resilience4j信号量隔离实现

POM引入依赖 <dependency><groupId>io.github.resilience4j</groupId><artifactId>resilience4j-bulkhead</artifactId><version>1.7.0</version> </dependency>信号量隔离修改YML文件 resilience4j:#信号量隔离bulkhead:ins…

GIT提示Another git process seems to be running in this repository

解决方法 1、进入项目里面的.git文件里面找到index.lock删除即可。

【算法】递归(高阶题目) -随时补充

文章目录 岛问题汉诺塔问题牛群繁衍数量问题求字符串的全部子序列字符串的全排列数字的全排列I数字的全排列IIN皇后IIN皇后I 岛问题 递归的方法: 遍历岛这个二维数组&#xff0c;如果当前数为1&#xff0c;则进入感染函数并将岛个数1感染函数&#xff1a;其实就是一个递归标注…

创建线程的4种方法

目录 一.前言 1.关于进程调度 (1)为什么要调度? (2)调度的真正对象 (3)调度的资源 2.线程 (1).线程的写法 (2)线程创建的方法 1.继承Thread (1)使用继承Thread,重写run的方式来创建线程 (2)继承Thread,使用匿名内部类 2.实现Runnable (1)使用实现Runnable,重写run…

自定义ElementPlus主题颜色

构建工具采用Vite CSS预处理器采用Sass 一.准备定制化的样式文件 1.安装Sass npm i sass -D 2.创建好文件目录 3.书写样式 ElementPlus默认样式. //index.scss/* 只需要重写你需要的即可 */ forward element-plus/theme-chalk/src/common/var.scss with ($colors: (prim…

pytorch固定随机数中种子

1、添加到yolov7的utils/general.py文件最下面 import pkg_resources as pkg def check_version(current0.0.0, minimum0.0.0, nameversion , pinnedFalse, hardFalse, verboseFalse):# Check version vs. required versioncurrent, minimum (pkg.parse_version(x) for x in …

【Verilog 教程】6.6Verilog 仿真激励

关键词&#xff1a;testbench&#xff0c;仿真&#xff0c;文件读写 Verilog 代码设计完成后&#xff0c;还需要进行重要的步骤&#xff0c;即逻辑功能仿真。仿真激励文件称之为 testbench&#xff0c;放在各设计模块的顶层&#xff0c;以便对模块进行系统性的例化调用进行仿真…

c#用Gnuplot画图源码

直接调用这个类即可&#xff0c;需要下载个GnuPlot安装下。 // Author: Leonardo Tazziniusing System; using System.Diagnostics; using System.Drawing; using System.IO; using System.Windows.Forms;/// <summary> /// Tested with Gnuplot 5.2 /// </summary&g…