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 left corner (row1, col1) and lower right corner (row2, col2). Range Sum Query 2D
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:
The matrix is only modifiable by the update function.
You may assume the number of calls to update and sumRegion function is distributed evenly.
You may assume that row1 ≤ row2 and col1 ≤ col2.
参考:https://leetcode.com/discuss/72685/share-my-java-2-d-binary-indexed-tree-solution
Build binary indexed tree takes : O(mn*logm*logn) time, both update() and getSum() take: O(logm*logn) time. The arr[][] is used to keep a backup of the matrix[][] so that we know the difference of the updated element and use that to update the binary indexed tree. The idea of calculating sumRegion() is the same as in Range Sum Query 2D - Immutable.
Summary of Binary Indexed Tree:
Binary Index Tree参见:https://www.youtube.com/watch?v=CWDQJGaN1gY
Compare Segment Tree vs Binary Indexed Tree
Segment Tree:
Time: O(N)build, O(logN)search, O(logN) update, space: O(NlogN)
Binary Indexed Tree:
Time: O(NlogN)build, O(logN) search, O(logN) update, space: O(N)
The advantage of Binary Indexed Tree over Segment Tree are:
require less space and very easy to implement
public class Solution {
int m, n;
int[][] arr; // stores matrix[][]
int[][] BITree; // 2-D binary indexed tree
public Solution(int[][] matrix) {
if (matrix.length == 0 || matrix[0].length == 0) {
return;
}
m = matrix.length;
n = matrix[0].length;
arr = new int[m][n];
BITree = new int[m + 1][n + 1];
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
update(i, j, matrix[i][j]); // init BITree[][]
}
}
}
public void update(int i, int j, int val) {
int diff = val - arr[i][j]; // get the diff
arr[i][j] = val; // update arr[][]
i++; j++;
for (int x=i; x<=m; x+=x&(-x)) {
for (int y=j; y<=n; y+=y&(-y)) {
BITree[x][y] += diff;
}
}
}
int getSum(int i, int j) {
int sum = 0;
i++; j++;
for (int x=i; x>0; x-=x&(-x)) {
for (int y=j; y>0; y-=y&(-y)) {
sum += BITree[x][y];
}
}
return sum;
}
public int sumRegion(int i1, int j1, int i2, int j2) {
return getSum(i2, j2) - getSum(i1-1, j2) - getSum(i2, j1-1) + getSum(i1-1, j1-1);
}
Introduction from GeeksforGeeks:
We have an array arr[0 . . . n-1]. We should be able to
1 Find the sum of first i elements.
2 Update value of a specified element of the array arr[i] = x where 0 <= i <= n-1.
A simple solution is to run a loop from 0 to i-1 and calculate sum of elements. To update a value, simply do arr[i] = x. The first operation takes O(n) time and second operation takes O(1) time. Another simple solution is to create another array and store sum from start to i at the i’th index in this array. Sum of a given range can now be calculated in O(1) time, but update operation takes O(n) time now. This works well if the number of query operations are large and very few updates.
Can we perform both the operations in O(log n) time once given the array?
One Efficient Solution is to use Segment Tree that does both operations in O(Logn) time.
Using Binary Indexed Tree, we can do both tasks in O(Logn) time. The advantages of Binary Indexed Tree over Segment are, requires less space and very easy to implement..
Representation
Binary Indexed Tree is represented as an array. Let the array be BITree[]. Each node of Binary Indexed Tree stores sum of some elements of given array. Size of Binary Indexed Tree is equal to n where n is size of input array. In the below code, we have used size as n+1 for ease of implementation.(index 0 is a dummy node)
Construction
We construct the Binary Indexed Tree by first initializing all values in BITree[] as 0. Then we call update() operation for all indexes to store actual sums, update is discussed below.
Operations
getSum(index): Returns sum of arr[0..index]
// Returns sum of arr[0..index] using BITree[0..n]. It assumes that
// BITree[] is constructed for given array arr[0..n-1]
1) Initialize sum as 0 and index as index+1.
2) Do following while index is greater than 0.
...a) Add BITree[index] to sum
...b) Go to parent of BITree[index]. Parent can be obtained by removing
the last set bit from index, i.e., index = index - (index & (-index))
3) Return sum.

The above diagram demonstrates working of getSum(). Following are some important observations.
Node at index 0 is a dummy node.
A node at index y is parent of a node at index x, iff y can be obtained by removing last set bit from binary representation of x.
A child x of a node y stores sum of elements from of y(exclusive y) and of x(inclusive x).
update(index, val): Updates BIT for operation arr[index] += val
// Note that arr[] is not changed here. It changes
// only BI Tree for the already made change in arr[].
1) Initialize index as index+1.
2) Do following while index is smaller than or equal to n.
...a) Add value to BITree[index]
...b) Go to next node of BITree[index]. Next node can be obtained by i.e., index = index + (index & (-index))
Leetcode: Range Sum Query 2D - Mutable && Summary: Binary Indexed Tree的更多相关文章
- [LeetCode] Range Sum Query 2D - Mutable 二维区域和检索 - 可变
Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...
- LeetCode Range Sum Query 2D - Mutable
原题链接在这里:https://leetcode.com/problems/range-sum-query-2d-mutable/ 题目: Given a 2D matrix matrix, find ...
- [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 ...
- 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 ...
- [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 ...
- LeetCode 308. Range Sum Query 2D - Mutable
原题链接在这里:https://leetcode.com/problems/range-sum-query-2d-mutable/ 题目: Given a 2D matrix matrix, find ...
- 308. Range Sum Query 2D - Mutable
题目: Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper ...
- [LeetCode] Range Sum Query 2D - Immutable
Very similar to Range Sum Query - Immutable, but we now need to compute a 2d accunulated-sum. In fac ...
- [Swift]LeetCode308. 二维区域和检索 - 可变 $ Range Sum Query 2D - Mutable
Given a 2D matrix matrix, find the sum of the elements inside the rectangle defined by its upper lef ...
随机推荐
- JS基础语法
1.注释语法://单行注释./*多行注释*/. 2.输出语法:{1.alert("要输出的字符串"):.alert(输出其类型): 2.confirm():弹出一个可以和用户交互 ...
- 【转】C#高性能大容量SOCKET并发(二):SocketAsyncEventArgs封装
http://blog.csdn.net/sqldebug_fan/article/details/17557341 1.SocketAsyncEventArgs介绍 SocketAsyncEvent ...
- C# 操作Cookie类
1.Cookie操作类 using System; using System.Data; using System.Configuration;using System.Web;using Syste ...
- Linq中常用的方法
这几天闲着也是闲着,就仔细的研究了一下Linq的语法,还有他的一些扩展方法的使用. 下面是一些常用的扩展方法. Aggregate 自定义的聚合计算 All 检测序列中所有元素是否都满足指定的条件 A ...
- Delphi xe7 FireMonkey / Mobile (Android, iOS)生成 QR Code完整实例
这个实例在windows.OS X.IOS和Android等平台运行正常.本文参考这个网站提供的方法:http://zarko-gajic.iz.hr/firemonkey-mobile-androi ...
- 【Android测试】【第三节】ADB——源码浅谈
◆版权声明:本文出自carter_dream的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/4651724.html 前言 由于本人精力 ...
- zepto源码--compact、flatten、camelize、dasherize、uniq--学习笔记
1.compact 删除数组中的空元素(不是空字符串).undefined.null 在定义变量时,定义过filter = emptyArray.filter,即调用javascript原生的数组处理 ...
- Cocos2d-JS引入其他场景小实例
创建新项目,目标是把LogoNode.js场景引入app.js 新建LogoNode.js var LogoLayer = cc.Layer.extend({ ctor:function () { t ...
- ArcGIS API for Silverlight 之ElementLayer使用及TextSymbol的模板使用
原文:ArcGIS API for Silverlight 之ElementLayer使用及TextSymbol的模板使用 在开发中动态在地图上添加文字信息,可以使用TextSymbol添加文字 // ...
- ASP.NET MVC3 Areas 分离项目 同名控制器(同名Controller) 演示demo
为什么需要分离? 我们知道MVC项目各部分职责比较清晰,相比较ASP.NET Webform而言,MVC项目的业务逻辑和页面展现较好地分离开来,这样的做法有许多优点,比如可测试,易扩展等等.但是在实际 ...