前缀和实现题目:二维区域和检索 - 矩阵不可变

article/2025/8/17 1:54:42

文章目录

  • 题目
    • 标题和出处
    • 难度
    • 题目描述
      • 要求
      • 示例
      • 数据范围
  • 前言
  • 解法
    • 思路和算法
    • 代码
    • 复杂度分析

题目

标题和出处

标题:二维区域和检索 - 矩阵不可变

出处:304. 二维区域和检索 - 矩阵不可变

难度

5 级

题目描述

要求

给定一个二维矩阵 matrix \texttt{matrix} matrix,处理以下类型的多个查询:

  • 计算以 (row1, col1) \texttt{(row1, col1)} (row1, col1) 为左上角、 (row2, col2) \texttt{(row2, col2)} (row2, col2) 为右下角的子矩阵元素的

实现 NumMatrix \texttt{NumMatrix} NumMatrix 类:

  • NumMatrix(int[] matrix) \texttt{NumMatrix(int[] matrix)} NumMatrix(int[] matrix) 使用矩阵 matrix \texttt{matrix} matrix 初始化对象。
  • int sumRegion(int row1, int col1, int row2, int col2) \texttt{int sumRegion(int row1, int col1, int row2, int col2)} int sumRegion(int row1, int col1, int row2, int col2) 返回矩阵 matrix \texttt{matrix} matrix 中的以 (row1, col1) \texttt{(row1, col1)} (row1, col1) 为左上角、 (row2, col2) \texttt{(row2, col2)} (row2, col2) 为右下角的子矩阵元素的

要求 sumRegion \texttt{sumRegion} sumRegion 的时间复杂度是 O(1) \texttt{O(1)} O(1)

示例

示例 1:

示例 1

输入:
["NumMatrix", "sumRegion", "sumRegion", "sumRegion"] \texttt{["NumMatrix", "sumRegion", "sumRegion", "sumRegion"]} ["NumMatrix", "sumRegion", "sumRegion", "sumRegion"]
[[[[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]]], [2, 1, 4, 3], [1, 1, 2, 2], [1, 2, 2, 4]] \texttt{[[[[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]]], [2, 1, 4, 3], [1, 1, 2, 2], [1, 2, 2, 4]]} [[[[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]]], [2, 1, 4, 3], [1, 1, 2, 2], [1, 2, 2, 4]]
输出:
[null, 8, 11, 12] \texttt{[null, 8, 11, 12]} [null, 8, 11, 12]
解释:
NumMatrix numMatrix = new NumMatrix([[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]]); \texttt{NumMatrix numMatrix = new NumMatrix([[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]]);} NumMatrix numMatrix = new NumMatrix([[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]]);
numMatrix.sumRegion(2, 1, 4, 3); \texttt{numMatrix.sumRegion(2, 1, 4, 3);} numMatrix.sumRegion(2, 1, 4, 3); // 返回 8 \texttt{8} 8(红色矩形框的元素和)
numMatrix.sumRegion(1, 1, 2, 2); \texttt{numMatrix.sumRegion(1, 1, 2, 2);} numMatrix.sumRegion(1, 1, 2, 2); // 返回 11 \texttt{11} 11(绿色矩形框的元素和)
numMatrix.sumRegion(1, 2, 2, 4); \texttt{numMatrix.sumRegion(1, 2, 2, 4);} numMatrix.sumRegion(1, 2, 2, 4); // 返回 12 \texttt{12} 12(蓝色矩形框的元素和)

数据范围

  • m = matrix.length \texttt{m} = \texttt{matrix.length} m=matrix.length
  • n = matrix[i].length \texttt{n} = \texttt{matrix[i].length} n=matrix[i].length
  • 1 ≤ m, n ≤ 200 \texttt{1} \le \texttt{m, n} \le \texttt{200} 1m, n200
  • -10 5 ≤ matrix[i][j] ≤ 10 5 \texttt{-10}^\texttt{5} \le \texttt{matrix[i][j]} \le \texttt{10}^\texttt{5} -105matrix[i][j]105
  • 0 ≤ row1 ≤ row2 < m \texttt{0} \le \texttt{row1} \le \texttt{row2} < \texttt{m} 0row1row2<m
  • 0 ≤ col1 ≤ col2 < n \texttt{0} \le \texttt{col1} \le \texttt{col2} < \texttt{n} 0col1col2<n
  • 最多调用 10 4 \texttt{10}^\texttt{4} 104 sumRegion \texttt{sumRegion} sumRegion 方法

前言

这道题是「区域和检索 - 数组不可变」的进阶,要求计算子矩阵的元素和。

这道题可以复用「区域和检索 - 数组不可变」的做法,计算矩阵每一行的一维前缀和,计算子矩阵的元素和时遍历子矩阵的每一行,但是该做法的每次查询的时间复杂度和查询范围的行数有关,无法实现 O ( 1 ) O(1) O(1) 时间的查询。使用二维前缀和,则可以实现 O ( 1 ) O(1) O(1) 时间的查询。

解法

思路和算法

为了实现 O ( 1 ) O(1) O(1) 时间的查询,需要预计算整个矩阵的前缀和矩阵。

创建 ( m + 1 ) × ( n + 1 ) (m + 1) \times (n + 1) (m+1)×(n+1) 的前缀和矩阵 prefixSums \textit{prefixSums} prefixSums,对于 0 ≤ i ≤ m 0 \le i \le m 0im 0 ≤ j ≤ n 0 \le j \le n 0jn prefixSums [ i ] [ j ] \textit{prefixSums}[i][j] prefixSums[i][j] 表示 matrix [ i ] \textit{matrix}[i] matrix[i] 的行数为 i i i、列数为 j j j 的前缀和,即行下标范围 [ 0 , i − 1 ] [0, i - 1] [0,i1]、列下标范围 [ 0 , j − 1 ] [0, j - 1] [0,j1] 中的所有元素之和:

prefixSums [ i ] [ j ] = ∑ 0 ≤ p < i , 0 ≤ q < j matrix [ p ] [ q ] \textit{prefixSums}[i][j] = \sum\limits_{0 \le p < i, 0 \le q < j} \textit{matrix}[p][q] prefixSums[i][j]=0p<i,0q<jmatrix[p][q]

特别地,当 i i i j j j 中至少有一个值等于 0 0 0 时, prefixSums [ i ] [ j ] = 0 \textit{prefixSums}[i][j] = 0 prefixSums[i][j]=0

对于 0 ≤ i < m 0 \le i < m 0i<m 0 ≤ j < n 0 \le j < n 0j<n prefixSums [ i + 1 ] [ j + 1 ] \textit{prefixSums}[i + 1][j + 1] prefixSums[i+1][j+1] 的值计算如下:

prefixSums [ i + 1 ] [ j + 1 ] = prefixSums [ i ] [ j + 1 ] + prefixSums [ i + 1 ] [ j ] − prefixSums [ i ] [ j ] + matrix [ i ] [ j ] \begin{aligned} &\textit{prefixSums}[i + 1][j + 1] \\ = &\textit{prefixSums}[i][j + 1] \\ &+ \textit{prefixSums}[i + 1][j] \\ &- \textit{prefixSums}[i][j] \\ &+ \textit{matrix}[i][j] \end{aligned} =prefixSums[i+1][j+1]prefixSums[i][j+1]+prefixSums[i+1][j]prefixSums[i][j]+matrix[i][j]

可以结合下图理解前缀和矩阵的计算方式。

图 1

图中的四个区域对应的原始矩阵的行下标范围和列下标范围如下。

  • A 区域的行下标范围是 [ 0 , i − 1 ] [0, i - 1] [0,i1],列下标范围是 [ 0 , j − 1 ] [0, j - 1] [0,j1]

  • B 区域的行下标范围是 [ 0 , i − 1 ] [0, i - 1] [0,i1],列下标是 j j j

  • C 区域的行下标是 i i i,列下标范围是 [ 0 , j − 1 ] [0, j - 1] [0,j1]

  • D 区域的行下标是 i i i,列下标是 j j j

前缀和 prefixSums [ i + 1 ] [ j + 1 ] \textit{prefixSums}[i + 1][j + 1] prefixSums[i+1][j+1] 应将 A、B、C、D 四个区域各计算一次。计算前缀和的各项中, prefixSums [ i ] [ j + 1 ] \textit{prefixSums}[i][j + 1] prefixSums[i][j+1] 为 A 区域和 B 区域, prefixSums [ i + 1 ] [ j ] \textit{prefixSums}[i + 1][j] prefixSums[i+1][j] 为 A 区域和 C 区域, prefixSums [ i ] [ j ] \textit{prefixSums}[i][j] prefixSums[i][j] 为 A 区域, matrix [ i ] [ j ] \textit{matrix}[i][j] matrix[i][j] 为 D 区域,因此可以通过上述方法计算前缀和矩阵。

得到前缀和矩阵 prefixSums \textit{prefixSums} prefixSums 之后,对于 0 ≤ row 1 ≤ row 2 < m 0 \le \textit{row}_1 \le \textit{row}_2 < m 0row1row2<m 0 ≤ col 1 ≤ col 2 < n 0 \le \textit{col}_1 \le \textit{col}_2 < n 0col1col2<n,以 ( row 1 , col 1 ) (\textit{row}_1, \textit{col}_1) (row1,col1) 为左上角、 ( row 2 , col 2 ) (\textit{row}_2, \textit{col}_2) (row2,col2) 为右下角的子矩阵的元素和可以通过前缀和矩阵得到:

sumRegion ( row 1 , col 1 , row 2 , col 2 ) = prefixSums [ row 2 + 1 ] [ col 2 + 1 ] − prefixSums [ row 1 ] [ col 2 + 1 ] − prefixSums [ row 2 + 1 ] [ col 1 ] + prefixSums [ row 1 ] [ col 1 ] \begin{aligned} &\textit{sumRegion}(\textit{row}_1, \textit{col}_1, \textit{row}_2, \textit{col}_2) \\ = &\textit{prefixSums}[\textit{row}_2 + 1][\textit{col}_2 + 1] \\ &- \textit{prefixSums}[\textit{row}_1][\textit{col}_2 + 1] \\ &- \textit{prefixSums}[\textit{row}_2 + 1][\textit{col}_1] \\ &+ \textit{prefixSums}[\textit{row}_1][\textit{col}_1] \end{aligned} =sumRegion(row1,col1,row2,col2)prefixSums[row2+1][col2+1]prefixSums[row1][col2+1]prefixSums[row2+1][col1]+prefixSums[row1][col1]

可以结合下图理解子矩阵元素和的计算方式。

图 2

图中的四个区域对应的原始矩阵的行下标范围和列下标范围如下。

  • A 区域的行下标范围是 [ 0 , row 1 − 1 ] [0, \textit{row}_1 - 1] [0,row11],列下标范围是 [ 0 , col 1 − 1 ] [0, \textit{col}_1 - 1] [0,col11]

  • B 区域的行下标范围是 [ 0 , row 1 − 1 ] [0, \textit{row}_1 - 1] [0,row11],列下标范围是 [ col 1 , col 2 ] [\textit{col}_1, \textit{col}_2] [col1,col2]

  • C 区域的行下标范围是 [ row 1 , row 2 ] [\textit{row}_1, \textit{row}_2] [row1,row2],列下标范围是 [ 0 , col 1 − 1 ] [0, \textit{col}_1 - 1] [0,col11]

  • D 区域的行下标范围是 [ row 1 , row 2 ] [\textit{row}_1, \textit{row}_2] [row1,row2],列下标范围是 [ col 1 , col 2 ] [\textit{col}_1, \textit{col}_2] [col1,col2]

需要计算元素和的子矩阵是 D 区域。计算子矩阵元素和的各项中, prefixSums [ row 2 + 1 ] [ col 2 + 1 ] \textit{prefixSums}[\textit{row}_2 + 1][\textit{col}_2 + 1] prefixSums[row2+1][col2+1] 为 A、B、C、D 四个区域, prefixSums [ row 1 ] [ col 2 + 1 ] \textit{prefixSums}[\textit{row}_1][\textit{col}_2 + 1] prefixSums[row1][col2+1] 为 A 区域和 B 区域, prefixSums [ row 2 + 1 ] [ col 1 ] \textit{prefixSums}[\textit{row}_2 + 1][\textit{col}_1] prefixSums[row2+1][col1] 为 A 区域和 C 区域, prefixSums [ row 1 ] [ col 1 ] \textit{prefixSums}[\textit{row}_1][\textit{col}_1] prefixSums[row1][col1] 为 A 区域,因此可以通过上述方法计算子矩阵元素和。

代码

class NumMatrix {int[][] prefixSums;public NumMatrix(int[][] matrix) {int m = matrix.length, n = matrix[0].length;prefixSums = new int[m + 1][n + 1];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {prefixSums[i + 1][j + 1] = prefixSums[i][j + 1] + prefixSums[i + 1][j] - prefixSums[i][j] + matrix[i][j];}}}public int sumRegion(int row1, int col1, int row2, int col2) {return prefixSums[row2 + 1][col2 + 1] - prefixSums[row1][col2 + 1] - prefixSums[row2 + 1][col1] + prefixSums[row1][col1];}
}

复杂度分析

  • 时间复杂度:构造方法的时间复杂度是 O ( m × n ) O(m \times n) O(m×n) sumRegion \textit{sumRegion} sumRegion 操作的时间复杂度是 O ( 1 ) O(1) O(1),其中 m m m n n n 分别是矩阵 matrix \textit{matrix} matrix 的行数和列数。构造方法需要创建 ( m + 1 ) × ( n + 1 ) (m + 1) \times (n + 1) (m+1)×(n+1) 的前缀和矩阵并计算每个元素的前缀和,每次 sumRegion \textit{sumRegion} sumRegion 操作计算子矩阵的元素和的时间是 O ( 1 ) O(1) O(1)

  • 空间复杂度: O ( m × n ) O(m \times n) O(m×n),其中 m m m n n n 分别是矩阵 matrix \textit{matrix} matrix 的行数和列数。需要创建 ( m + 1 ) × ( n + 1 ) (m + 1) \times (n + 1) (m+1)×(n+1) 的前缀和矩阵。


http://www.hkcw.cn/article/yhvmUpfVMs.shtml

相关文章

《碟中谍8》阿汤哥水下戏几乎盲拍 重装挑战极限

《碟中谍8》于5月23日在北美地区上映,片长2小时49分钟,烂番茄新鲜度为80%,观众评分为89%。派拉蒙官方发布了该电影的片段,展示了阿汤哥在水下的特技表演。现年62岁的阿汤哥透露,在拍摄这个水下镜头时,他所穿的潜水服重达125磅(约113.4斤),只能穿着10分钟,之后就会缺氧…

荔枝竟会导致低血糖!千万别多吃 当心“荔枝病”

又到了荔枝上市的甜蜜季节果肉晶莹,口感清甜让人忍不住一颗接一颗然而这两天话题#荔枝病#登上社交平台热搜榜据报道,近日,广东一女子过量食用10斤荔枝,次日睡醒出现头晕不适、持续性鼻出血等症状,紧急就医后被诊断为“荔枝病”。网友纷纷惊讶留言“还有这种病?”荔枝会让…

男子翻女友手机发现女友未婚夫 女方:就是牌友而已

河南许昌,刘先生称和女友恋爱2年多,女友比自己大5岁带三个娃,相处期间两人很和睦,自己给对方还房贷,孩子都叫自己爸爸了,却意外发现她手机里还有男朋友,备注叫大哥。女方:我和刘先生就是牌友,和手机里男友的马上要结婚了,给的钱全是打牌的钱...随后,女方正牌男友来到…

民警吃个饭就能识破骗局!成功保住店主30万元

民警吃个饭,就能识破骗局。事情发生在云南,民警田铁林来到一家馄饨店,落座后,却发现老板娘不仅迟迟没有清理餐桌,还一直在通电话。凭借职业警觉,他发现了其中的问题。经过简单沟通,田铁林意识到,老板娘玉女士很可能正在经历电信网络诈骗。当看到与老板娘玉女士通话的号…

《碟中谍8》上映 阿汤哥再现极限特技

5月30日,《碟中谍8:最终清算》将在中国内地上映。从1996年到2025年,该系列已经陪伴了我们近30年。“阿汤哥”汤姆克鲁斯扮演的特工伊森亨特身手不凡、勇敢无畏、智勇双全。在拍摄过程中,他坚持不用替身,亲自完成了许多高难度和高风险的特技动作,让观众沉浸式感受到真实的…

曝华为正开发首款折叠平板 大屏便携新选择

华为在折叠屏领域已处于全球领先地位,拥有最全面的折叠屏产品线。目前,华为推出了小折叠、阔折叠、外折叠、内折叠、三折叠以及折叠PC等多种形态的产品。博主数码闲聊站透露,华为正在开发可折叠平板设备,但具体信息尚未明确。根据现有的折叠屏手机和电脑形态推测,这款折叠…

15岁少年被困!这条“死亡沸腾线”有多可怕?

近日一名15岁少年被困浙江省衢州市乌溪江巨化中学段滚水坝情况危急现场无人机画面显示少年所在位置距坝底落差近3米坝下滚水区形成强烈漩涡一旦少年体力不支被卷入水中极可能发生溺水事故滚水坝下游水流具有强吸力常规救援难以靠近在无人机导航下消防员采取“船头调向抵消水流”…

Labubu二手市场身价数万元 绝版老款成抢手货

由于安全风险上升,泡泡玛特已宣布暂停Labubu在英国的销售,并计划在6月前将该产品从英国门店全面下架。Labubu是泡泡玛特旗下IP,已从一款小众设计师玩偶跃升为国际潮流偶像。最新上市的Labubu系列在美国、英国等地经常“几分钟内”售罄。由于需求火爆,近日伦敦斯特拉特福德韦…

Cursor系列(1):Cursor安装、虚拟环境

1 安装Cursor 下载地址如下&#xff1a; Cursor - The AI Code Editor 2 插件安装 在扩展中搜索你要安装的插件包&#xff1a; 如下&#xff1a; 安装中文汉化插件&#xff1a; 安装完以后需要重启Cursor&#xff0c;插件才能生效。 安装python环境插件&#xff0c;如下&a…

用户隐私如何在Facebook的大数据中得到保护?

在这个数字化时代&#xff0c;用户隐私保护成为了一个全球性的问题。Facebook作为全球最大的社交媒体平台之一&#xff0c;拥有海量的用户数据。这些数据不仅包括用户的基本信息&#xff0c;还涉及到用户的行为习惯、兴趣爱好等。因此&#xff0c;如何在大数据中保护用户隐私成…

男子徒步途中捡到巨型菌子激动到破音 温馨提示:切勿随意采摘与食用野生菌

近日,云南西双版纳,男子徒步时捡到巨型菌子,激动到破音!网友:第一次听到牛肝菌叫!温馨提示,切勿随意采摘与食用野生菌。责任编辑:zx0002

京东向抚养3弟妹的05后骑手致敬 已与其签订正式劳动合同缴纳五险一金

近日,江苏沭阳一名2005年出生的女孩陈姑娘(化名)因家庭变故,独自承担起抚养3个弟妹的责任,引发热议。5月29日,@京东外卖发文:“骑手小姐姐自立自强的故事让人感动,我们向她致敬,也向千千万万的骑手伙伴们致敬!”此前据媒体报道,陈姑娘父亲于2017年确诊肠癌,当时陈姑…

店长回应女店员被男子骚扰 店长及时制住男子

近日,网传视频显示,在湖北襄阳的一家烤肉店门口,一名女店员正在招揽生意。5月27日,一名路过男子突然伸手摸向女店员的腰部,女店员本能地缩了下身子。随后,她与该男子理论,过程中另一名店员也介入。男子转身离开,但没走几步又扭头回来,对女店员动了手,两人扭打在一起,…

断眉歌手唱SeeYouAgain 长沙演唱会即将开启

《歌手2025》节目组于30日宣布,本期袭榜歌手为“断眉”查理普斯。此外,查理普斯的长沙演唱会也已正式公布,将于2025年7月12日在长沙贺龙体育场举行。票价从399元到1699元不等,目前尚未开始售票,但官方表示即将公布具体的开票信息。责任编辑:0764

2025python实战:利用海外代理IP验证广告投放效果

你有没有遇到这种场景&#xff1a;团队投放了一个海外广告&#xff0c;明明预算烧了不少&#xff0c;却心里七上八下&#xff0c;担心广告到底在目标区域是否好好展示&#xff1f;可能东南亚的消费者该看到折扣广告&#xff0c;美国那边应该秀新品发布……但问题是&#xff0c;…

收房后送检入户门 精装四千一平业主说房门耐火不达标

蒋女士在杭州众安岚荷芸府小区买了房,今年1月精装修交付。她说小区装修标准是每平方4000元,有业主送检了入户门,显示耐火性能不达标。记者跟房门厂家取得了联系,对于送检流程,那头表示有疑问。责任编辑:zx0002

日本抢购大米网站崩了!网页一度因点击量过高无法打开

为平抑持续飙升的米价,日本政府29日通过网络平台限量发售最新一批储备米。这批储备米共约22万吨,大部分产于2022年,政府指导零售价为每5公斤2160日元,约合107元人民币,相当于当前市场平均价的约一半。多家网络平台的储备米在一两个小时内就售罄,有购物网站相关网页一度因…

金饰克价再涨破千元 国内金价跟涨

美东时间5月29日,国际金价出现反弹。现货黄金上涨0.96%,达到3317.8美元/盎司;COMEX黄金期货上涨0.61%,报3342.6美元/盎司;COMEX白银期货也上涨了0.84%,达到33.44美元/盎司。然而,早间金价再度下跌,现货黄金微跌0.02%,报3316.6美元/盎司;COMEX黄金期货则下跌0.17%,报…

皮划艇被浪打翻男子海上漂流7小时:差点被路过的货轮撞飞

皮划艇被浪打翻男子海上漂流7小时 绝望漂流终获救!5月29日,广东一名男子分享了自己在庙湾岛附近划皮划艇时遭遇的惊险经历。他在海上遇到了测浪船被打翻的情况,手机没有信号且大船无法看到他。在这段时间里,他还差点撞上了一艘货轮,在海中绝望地漂流了七个小时,漂流了大约…

中专→大专→本科→北大研究生!谢欣宇太厉害了

中专→大专→本科→北大研究生今年4月河南学子谢欣宇收到了来自北京大学的录取通知她凭借坚持不懈的毅力和执着用近十年的时间最终从中专一路逆袭考上北大研究生她的故事也激励了很多网友01谢欣宇是河南信阳淮滨县人从信阳职业技术学院护理学院2016级护理专业(中专)2019级护理…