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 ...
随机推荐
- jq tab
<div id="outer"> <ul id="tab"> <li class="current">t ...
- Programming In hardware Programming in software
COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION
- ease of rerouting traffic in IP networks without readdressing every host
https://en.wikipedia.org/wiki/Network_address_translation In the face of the foreseeable global IP a ...
- IE 的resize事件问题
window的resize事件,真的让人无语! 我在动态设置元素的HTML内容后,窗口高度变化了,可是却不触发resize事件. 但是我在访问document.documentElement.scro ...
- Bootstrap 路径分页标签和徽章组件
一.路径组件 路径组件也叫做面包屑导航. //面包屑导航 <ol class="breadcrumb"> <li><a href="#&qu ...
- PHP实现QQ第三方登录
PHP实现QQ第三方登录 学习之前,请大家先看一下oAuth协议. 首先呢,我们进入QQ互联的官方网站 http://connect.qq.com登入我们自己的QQ号,没有QQ号的小伙伴可以忽略本篇博 ...
- android Textview动态设置大小
import android.app.Activity; //import com.travelzen.tdx.BaseActivity; //import com.travelzen.tdx.uti ...
- 简单计算器--hdu1237(栈的运用)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1237 这是单纯的本题答案: #include<stdio.h> #define N 11 ...
- 解决在.ashx文件中判断Session 总是NULL的方法
实现IHttpHandler接口的同时必须继承IRequiresSessionState接口,才能拿到session public class HttpHandler: IHttpHandler, I ...
- UIWebView相关设置
让UIWebView的背景透明: 1 2 self.webView.backgroundColor = [UIColor clearColor]; self.webView.opaque = NO 这 ...