Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper left corner (row1, col1) and lower right corner (row2, col2).


The above rectangle (with the red border) is defined by (row1, col1) = (2, 1) and (row2, col2) = (4, 3), which contains sum = 8.

Example:

Given matrix = [
[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]
] sumRegion(2, 1, 4, 3) -> 8
update(3, 2, 2)
sumRegion(2, 1, 4, 3) -> 10

Note:

  1. The matrix is only modifiable by the update function.
  2. You may assume the number of calls to update and sumRegion function is distributed evenly.
  3. You may assume that row1 ≤ row2 and col1 ≤ col2.

这道题让我们求二维区域和检索,而且告诉我们数组中的值可能变化,这是之前那道Range Sum Query 2D - Immutable的拓展,由于我们之前做过一维数组的可变和不可变的情况Range Sum Query - MutableRange Sum Query - Immutable,那么为了能够通过OJ,我们还是需要用到树状数组Binary Indexed Tree(参见Range Sum Query - Mutable),其查询和修改的复杂度均为O(logn),那么我们还是要建立树状数组,我们根据数组中的每一个位置,建立一个二维的树状数组,然后还需要一个getSum函数,以便求得从(0, 0)到(i, j)的区间的数字和,然后在求某一个区间和时,就利用其四个顶点的区间和关系可以快速求出,参见代码如下:

解法一:

// Binary Indexed Tree
class NumMatrix {
public:
NumMatrix(vector<vector<int>> &matrix) {
if (matrix.empty() || matrix[].empty()) return;
mat.resize(matrix.size() + , vector<int>(matrix[].size() + , ));
bit.resize(matrix.size() + , vector<int>(matrix[].size() + , ));
for (int i = ; i < matrix.size(); ++i) {
for (int j = ; j < matrix[i].size(); ++j) {
update(i, j, matrix[i][j]);
}
}
} void update(int row, int col, int val) {
int diff = val - mat[row + ][col + ];
for (int i = row + ; i < mat.size(); i += i&-i) {
for (int j = col + ; j < mat[i].size(); j += j&-j) {
bit[i][j] += diff;
}
}
mat[row + ][col + ] = val;
} int sumRegion(int row1, int col1, int row2, int col2) {
return getSum(row2 + , col2 + ) - getSum(row1, col2 + ) - getSum(row2 + , col1) + getSum(row1, col1);
} int getSum(int row, int col) {
int res = ;
for (int i = row; i > ; i -= i&-i) {
for (int j = col; j > ; j -= j&-j) {
res += bit[i][j];
}
}
return res;
} private:
vector<vector<int>> mat;
vector<vector<int>> bit;
};

我在网上还看到了另一种解法,这种解法并没有用到树状数组,而是利用了列之和,所谓列之和,就是(i, j)就是(0, j) + (1, j) + ... + (i, j) 之和,相当于把很多个一维的区间之和拼到了一起,那么我们在构造函数中需要建立起这样一个列之和矩阵,然后再更新某一个位置时,我们只需要将该列中改变的位置下面的所有数字更新一下即可,而在求某个区间和时,只要将相差的各列中对应的起始和结束的行上的值的差值累加起来即可,参见代码如下:

解法二:

// Column Sum
class NumMatrix {
public:
NumMatrix(vector<vector<int>> &matrix) {
if (matrix.empty() || matrix[].empty()) return;
mat = matrix;
colSum.resize(matrix.size() + , vector<int>(matrix[].size(), ));
for (int i = ; i < colSum.size(); ++i) {
for (int j = ; j < colSum[].size(); ++j) {
colSum[i][j] = colSum[i - ][j] + matrix[i - ][j];
}
}
} void update(int row, int col, int val) {
for (int i = row + ; i < colSum.size(); ++i) {
colSum[i][col] += val - mat[row][col];
}
mat[row][col] = val;
} int sumRegion(int row1, int col1, int row2, int col2) {
int res = ;
for (int j = col1; j <= col2; ++j) {
res += colSum[row2 + ][j] - colSum[row1][j];
}
return res;
} private:
vector<vector<int>> mat;
vector<vector<int>> colSum;
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/308

类似题目:

Range Sum Query 2D - Immutable

Range Sum Query - Mutable

Range Sum Query - Immutable

参考资料:

https://leetcode.com/problems/range-sum-query-2d-mutable/

https://leetcode.com/problems/range-sum-query-2d-mutable/discuss/75852/15ms-easy-to-understand-java-solution

https://leetcode.com/problems/range-sum-query-2d-mutable/discuss/75870/Java-2D-Binary-Indexed-Tree-Solution-clean-and-short-17ms

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Range Sum Query 2D - Mutable 二维区域和检索 - 可变的更多相关文章

  1. [LeetCode] Range Sum Query 2D - Immutable 二维区域和检索 - 不可变

    Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...

  2. [LeetCode] 304. Range Sum Query 2D - Immutable 二维区域和检索 - 不可变

    Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...

  3. LeetCode 304. Range Sum Query 2D - Immutable 二维区域和检索 - 矩阵不可变(C++/Java)

    题目: Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper ...

  4. 304 Range Sum Query 2D - Immutable 二维区域和检索 - 不可变

    给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2). 上图子矩阵左上角 (row1, col1) = (2, 1) ,右 ...

  5. Leetcode: Range Sum Query 2D - Mutable && Summary: Binary Indexed Tree

    Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...

  6. LeetCode Range Sum Query 2D - Mutable

    原题链接在这里:https://leetcode.com/problems/range-sum-query-2d-mutable/ 题目: Given a 2D matrix matrix, find ...

  7. [leetcode]304. Range Sum Query 2D - Immutable二维区间求和 - 不变

    Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...

  8. Range Sum Query 2D - Mutable & Immutable

    Range Sum Query 2D - Mutable Given a 2D matrix matrix, find the sum of the elements inside the recta ...

  9. [Locked] Range Sum Query 2D - Mutable

    Range Sum Query 2D - Mutable Given a 2D matrix matrix, find the sum of the elements inside the recta ...

随机推荐

  1. 2.ASP.NET MVC 中使用Crystal Report水晶报表

    上一篇,介绍了怎么导出Excel文件,这篇文章介绍在ASP.NET MVC中使用水晶报表. 项目源码下载:https://github.com/caofangsheng93/CrystalReport ...

  2. 在DevExpress程序中使用SplashScreenManager控件实现启动闪屏和等待信息窗口

    在我很早的WInform随笔<WinForm界面开发之"SplashScreen控件">有介绍如何使用闪屏的处理操作,不过那种是普通WInform和DevExpress ...

  3. C# 视频编辑

    VidCoder VidCoder是一个开源免费的DVD/蓝光视频抓取和转码软件.使用HandBrake做为编码引擎.比Handbrake拥有更友好的用户界面. 可裁剪.剪切.字幕编辑.转码等. 官网 ...

  4. Devexress XPO xpPageSelector 使用

    在官网找到的.在这里做个备注. private void simpleButton1_Click(object sender, EventArgs e) { ) return; xpPageSelec ...

  5. wpf 列表、菜单 收起与展开,通过Grid DoubleAnimation或者Expander实现

    菜单收缩有很多种方法具体如何实现还是看个人想法: 第一种通过后台控制收起与展开: 效果图: 代码 : <Grid> <Grid.ColumnDefinitions> <C ...

  6. Linux:JDK配置

    1.JDK官网下载"jdk-8u101-linux-i586.tar.gz",32位或64位. 2 命令 #创建jdk所在目录 sudo mkdir /usr/lib/jvm #找 ...

  7. 《连载 | 物联网框架ServerSuperIO教程》- 11.实现设备(驱动)与设备(驱动)交互和级联控制。注:设备驱动模拟金三与普京的对话

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  8. webuploader上传文件,图片

    WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件.官方地址:http://fex.baidu.com/webupload ...

  9. Mybatis框架的模糊查询(多种写法)、删除、添加(四)

    学习Mybatis这么多天,那么我给大家分享一下我的学习成果.从最基础的开始配置. 一.创建一个web项目,看一下项目架构 二.说道项目就会想到需要什么jar 三.就是准备大配置链接Orcl数据库 & ...

  10. Mac下安装ElasticSearch

    简单记录一下安装ES的过程,给小小白们提供一下参考: 下载安装包 https://www.elastic.co/downloads/elasticsearch建议下载2.3.2版本,最新的5.0.0版 ...