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

2023-09-20 15:47:30

题目

输入一个二维矩阵,如何计算给定左上角坐标和右下角坐标的子矩阵的数字之和?对于同一个二维矩阵,计算子矩阵的数字之和的函数可能由于输入不同的坐标而被反复调用多次。例如,输入图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的情形。

更多推荐

什么是网络安全?网络安全包括哪几个方面?

提及网络安全,很多人都是既熟悉又陌生,所谓的熟悉就是知道网络安全可以保障网络服务不中断。那么到底什么是网络安全?网络安全包括哪几个方面?通过下文为大家介绍一下。什么是网络安全?网络安全是指网络系统的硬件、软件及系统中的数据受到保护,不因偶然的或者恶意的原因而遭受到破坏、更改、泄露,系统连续可靠正常地运行,网络服务不中断

由于数字化转型对集成和扩展性的要求,定制化需求难以满足,百数低代码服务商该如何破局?

当政策、技术环境的日益成熟,数字化转型逐步成为企业发展的必选项,企业数字化转型不再是一道选择题,而是决定其生存发展的必由之路。通过数字化转型升级生产方式、管理模式和组织形式,激发内生动力,成为企业顺应时代变化,实现高质量发展的必然选择。一般来说,实现数字化转型的方式有3种:采购已有的标准系统、定制外包或者选购低代码平台

iOS17适配指南-新版

文章目录一、iOS17适配点二、具体代码一、iOS17适配点UIView与UIViewController。可以设置数据为空时的占位视图,增加SymbolAnimations,通过addSymbolEffect()与removeSymbolEffect()方法,可以实现SFSymbols图标的添加与移除动画。UIPag

通讯网关软件007——利用CommGate X2Mbt实现Modbus TCP访问MSSQL服务器

本文介绍利用CommGateX2Mbt实现ModbusTCP访问MSSQL数据库。CommGateX2MBT是宁波科安网信开发的网关软件,软件可以登录到网信智汇(wangxinzhihui.com)下载。【案例】如下图所示,实现上位机通过ModbusTCP来获取MSSQL数据库的数据。【解决方案】设置网关机,与MSSQ

【Java核心】JDK、JRE、 JVM的联系与区别

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~个人主页:.29.的博客学习社区:进去逛一逛~JDK、JRE、JVM的联系与区别1.简述2.是什么3.联系和区别1.简述简单来说:JDK是开发Java程序所需的工具包,包含了JRE,并且额外提供了开发工

Linux高性能服务器编程 学习笔记 第四章 TCP/IP通信案例:访问Internet上的Web服务器

Web客户端和服务器之间使用HTTP协议通信。我们按以下方式来部署通信实例:在Kongming20上运行wget客户端程序(一个在命令行下使用的网络下载工具,它支持通过HTTP、HTTPS和FTP协议下载文件),在ernest-laptop上运行squid代理服务器程序(主要用于缓存和转发网络请求,从而提高网络性能、安

免费IP类api接口:含ip查询、ip应用场景查询、ip代理识别、IP行业查询...

免费IP类api接口:含ip查询、ip应用场景查询、ip代理识别…IP归属地-IPv6区县级:根据IP地址(IPv6版本)查询归属地信息,包含国家、省、市、区县和运营商等信息。IP归属地-IPv6城市级:根据IP地址(IPv6版本)查询归属地信息,支持到中国大陆地区(不含港澳台地区)城市级别,包含国家、省、市和运营商等

酷开科技打造更好体验服务用户

智能电视以其海量资源、智慧大屏、高清画质等特点在国内快速普及。然而,随着用户量的增加、用户群体的需求多元化,导致消费者对智能电视的应用要求越来越高,不仅希望智能电视内容丰富,最好还能拥有“多合一”的功能。好在,一些科技企业关注到市场痛点,致力于将技术创新与完善的内容输出相结合,为广大消费者带来更多惊喜。酷开科技就是其中

Kafka开篇

前言从本篇开始对个人Kafka学习做一个总结,目标有这么几个。从概念架构角度,对消息中间件形成概要认知;从使用角度,掌握其常见用法;从性能角度,探究其高性能实现机制;消息中间件的用途从消息生产和消费的角度,平衡消费者和消费者的速率差。基于该点可以做到削峰填谷,比如流量突发,日志处理等。从系统解耦的角度,解耦生产者和消费

React 全栈体系(九)

第五章React路由一、相关理解1.SPA的理解单页Web应用(singlepagewebapplication,SPA)。整个应用只有一个完整的页面。点击页面中的链接不会刷新页面,只会做页面的局部更新。数据都需要通过ajax请求获取,并在前端异步展现。2.路由的理解2.1什么是路由?一个路由就是一个映射关系(key:

Mysql的常见错误总结

Mysql的常见错误总结Datatruncation:Outofrangevalueofforcolumn在执行一个update语句的时候,报错Datatruncation:Outofrangevalueofforcolumn‘CLAIM_QUANTITY’…update语句是把’CLAIM_QUANTITY’这个字段

热文推荐