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.
Update value of a specified element of the array arr[i] = x where 0 <= i <= n-1.

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的更多相关文章

  1. [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 ...

  2. LeetCode Range Sum Query 2D - Mutable

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

  3. [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 ...

  4. 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 ...

  5. [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 ...

  6. LeetCode 308. Range Sum Query 2D - Mutable

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

  7. 308. Range Sum Query 2D - Mutable

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

  8. [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 ...

  9. [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 ...

随机推荐

  1. Sphinx+MySQL5.1x+SphinxSE+mmseg

    一.不停止mysql的情况下安装SphinxSE 1.确定mysql版本,下载对应源码包 此处下载5.1.69的mysql源码包 #wget ftp://ftp.ntu.edu.tw/pub/MySQ ...

  2. LVS的DR模式配置

    一.基本规划负载均衡调度器    192.168.1.104    默认网关    192.168.1.1    ip别名    192.168.1.233realserver1    192.168 ...

  3. lvs nginx HAProxy优缺点

    LVS的优点:1、抗负载能力强、工作在第4层仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的;无流量,同时保证了均衡器IO的性能不会受到大流量的影响;2、工作稳定,自身有完 ...

  4. 3.PHP内核探索:一次请求生命周期

    我们从未手动开启过PHP的相关进程,它是随着Apache的启动而运行的.PHP通过mod_php5.so模块和Apache相连(具体说来是SAPI,即服务器应用程序编程接口). PHP总共有三个模块: ...

  5. Scrapy安装介绍

    一. Scrapy简介 Scrapy is a fast high-level screen scraping and web crawling framework, used to crawl we ...

  6. 依赖注入Bean属性

    一.Bean属性依赖注入 对于类成员变量,注入方式有三种 •构造函数注入 •属性setter方法注入 •接口注入 Spring支持前两种 1.构造函数 属性注入 使用构造方法注入,在Spring配置文 ...

  7. spring-3-mvc-hello-world-example

    http://www.mkyong.com/spring3/spring-3-mvc-hello-world-example/

  8. http://d3js.org/

    http://d3js.org/ http://www.ourd3js.com/wordpress/?p=51 http://www.ourd3js.com/wordpress/?p=104file: ...

  9. Abstract Algebra chapter 7

    7.7:Encrypt each of the following RSA messages x so that x is divided into blocks of integers of len ...

  10. MySQL-中文全文检索

    一.概述 MySQL全文检索是利用查询关键字和查询列内容之间的相关度进行检索,可以利用全文索引来提高匹配的速度. 二.语法 1 2 MATCH (col1,col2,...) AGAINST (exp ...