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. Oracle数据库异机升级

    环境: A机:RHEL5.5 + Oracle 10.2.0.4 B机:RHEL5.5 需求: A机10.2.0.4数据库,在B机升级到11.2.0.4,应用最新PSU补丁程序. 目录: 一. 确认是 ...

  2. 谈谈React那些小事

    前言 说起React,那也是近一年多时间火起来的前端框架,其在Facebook的影响力和大力推广下,已然成为目前前端界的中流砥柱.在如今的前端框架界,React.Vue.Angular三分天下的时代已 ...

  3. C#开发微信门户及应用(24)-微信小店货架信息管理

    在前面微信小店系列篇<C#开发微信门户及应用(22)-微信小店的开发和使用>里面介绍了一些微信小店的基础知识,以及<C#开发微信门户及应用(23)-微信小店商品管理接口的封装和测试& ...

  4. Springl利用Aspectj的扩展实现Aop

    1. Spring为什么要使用Aspectj Spring Aop:Spring自己原生的Aop,只能用一个词来形容:难用. 你需要实现大量的接口,继承大量的类,所以spring aop一度被千夫所指 ...

  5. 利用Spring AOP机制拦截方法一例

    直接上代码: @Aspect // for aop @Component // for auto scan @Order(0) // execute before @Transactional pub ...

  6. RPC是什么?科普一下

    RPC概念及分类 RPC全称为Remote Procedure Call,翻译过来为“远程过程调用”.目前,主流的平台中都支持各种远程调用技术,以满足分布式系统架构中不同的系统之间的远程通信和相互调用 ...

  7. C#通过反射给对象赋值

    class Program { static void Main(string[] args) { UserSearchRequest model = new UserSearchRequest() ...

  8. jasmine test 页面测试工具

    before((request, response) -> { response.header("Access-Control-Allow-Origin", "ht ...

  9. SAP CRM 7.0中的BOL(Business Object Layer)

    业务对象层(BOL)和通用交互层(GenIL)属于业务层. 业务对象层:   在CRM WebClient会话运行期间,业务对象层存储业务对象的数据以及它们属性和关系的定义. 通用交互层 通用交互层将 ...

  10. dotnet core 使用 MongoDB 进行高性能Nosql数据库操作

    好久没有写过Blog, 每天看着开源的Java社区流口水, 心里满不是滋味. 终于等到了今年六月份 dotnet core 的正式发布, 看着dotnet 社区也一步一步走向繁荣, 一片蒸蒸日上的大好 ...