303. Range Sum Query - Immutable && 304. Range Sum Query 2D - Immutable && 307. Range Sum Query - Mutable && 308. Range Sum Query 2D - Mutable
303. Range Sum Query - Immutable
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.Example:
Given nums = [-2, 0, 3, -5, 2, -1] sumRange(0, 2) -> 1 sumRange(2, 5) -> -1 sumRange(0, 5) -> -3
Note:
- You may assume that the array does not change.
- There are many calls to sumRange function.
public class NumArray { private int[] sums = null; public NumArray(int[] nums) { for(int i =1; i<nums.length; ++i) { nums[i] += nums[i-1]; } sums = nums; } public int sumRange(int i, int j) { if(i == 0) return sums[j]; return sums[j] - sums[i-1]; } } // Your NumArray object will be instantiated and called as such: // NumArray numArray = new NumArray(nums); // numArray.sumRange(0, 1); // numArray.sumRange(1, 2);
304. Range Sum Query 2D - Immutable
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 sumRegion(1, 1, 2, 2) -> 11 sumRegion(1, 2, 2, 4) -> 12
Note:
- You may assume that the matrix does not change.
- There are many calls to sumRegion function.
- You may assume that row1 ≤ row2 and col1 ≤ col2.
public class NumMatrix { private int[][] sums; //This keeps a sum from (0,0) to (row+1, col+1) public NumMatrix(int[][] matrix) { if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return; int row = matrix.length; int col = matrix[0].length; sums = new int[row + 1][col + 1]; for (int r = 1; r <= row; ++r) { for (int c = 1; c <= col; ++c) { sums[r][c] = sums[r - 1][c] + sums[r][c - 1] - sums[r - 1][c - 1] + matrix[r - 1][c - 1]; } } } public int sumRegion(int row1, int col1, int row2, int col2) { return sums[row2 + 1][col2 + 1] - sums[row2 + 1][col1] - sums[row1][col2 + 1] + sums[row1][col1]; } } // Your NumMatrix object will be instantiated and called as such: // NumMatrix numMatrix = new NumMatrix(matrix); // numMatrix.sumRegion(0, 1, 2, 3); // numMatrix.sumRegion(1, 2, 3, 4);
307. Range Sum Query - Mutable
Given an integer array nums, find the sum of the elements between indices i and j (i ≤ j), inclusive.
The update(i, val) function modifies nums by updating the element at index i to val.Example:
Given nums = [1, 3, 5] sumRange(0, 2) -> 9 update(1, 2) sumRange(0, 2) -> 8
Note:
- The array is only modifiable by the update function.
- You may assume the number of calls to update and sumRange function is distributed evenly.
Both update and getSum is O(logn).
Fenwick Tree(Binary Indexed Tree) References:
http://www.geeksforgeeks.org/binary-indexed-tree-or-fenwick-tree-2/
https://en.wikipedia.org/wiki/Fenwick_tree
https://www.youtube.com/watch?v=CWDQJGaN1gY
Segment Tree References:
https://en.wikipedia.org/wiki/Segment_tree
Fenwick Tree Solution (which is faster than the segment tree solution.)
public class NumArray { private int[] tree; private int[] nums; public NumArray(int[] nums) { this.tree = new int[nums.length + 1]; //First node for Fenwick Tree is a dummy node. this.nums = nums; for (int i = 0; i < nums.length; ++i) { updateTree(i, nums[i]); } } private void updateTree(int i, int deltaDiff) { i += 1; while (i <= nums.length) { tree[i] += deltaDiff; i += i & (-i); // get the last bit, and add to itself to update its next pointer. } } public void update(int i, int val) { updateTree(i, val - nums[i]); nums[i] = val; } private int getSum(int i) { i += 1; int sum = 0; while (i > 0) { sum += tree[i]; i -= i & (-i);// get the last bit, and subtract to itself to get its parent. } return sum; } public int sumRange(int i, int j) { if (i == 0) return getSum(j); return getSum(j) - getSum(i - 1); } } // Your NumArray object will be instantiated and called as such: // NumArray numArray = new NumArray(nums); // numArray.sumRange(0, 1); // numArray.update(1, 10); // numArray.sumRange(1, 2);
Segment Tree Solution (which is slower than the Fenwick tree solution):
public class NumArray { private class TreeNode { private int start; private int end; int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int start, int end) { this.start = start; this.end = end; } } private TreeNode root = null; private int[] nums = null; //[start, end] // alternatively, you can build the tree using an array, like doing heap sort. // check this youtube: // https://www.youtube.com/watch?annotation_id=32b44f2a-e16f-4fb3-821d-cf0834915b9c&feature=cards&src_vid=CWDQJGaN1gY&v=ZBHKZF5w4YU private TreeNode build(int start, int end) { TreeNode node = new TreeNode(start, end); if (start == end) { node.val = nums[start]; return node; } int mid = start + (end - start) / 2; node.left = build(start, mid); node.right = build(mid + 1, end); node.val = node.left.val + node.right.val; return node; } private void update(TreeNode node, int i, int update) { if (node == null) return; if (node.start == node.end) { // at leaf nodes. node.val = update; //update leaf node. return; } int mid = node.start + (node.end - node.start) / 2; if (i <= mid) update(node.left, i, update); // at left branch else update(node.right, i, update); // at right branch node.val = node.left.val + node.right.val; //update current node } //[start, end] private int getSum(TreeNode node, int start, int end) { start = Math.max(start, node.start); end = Math.min(end, node.end); if (start == node.start && end == node.end) return node.val; int mid = node.start + (node.end - node.start) / 2; if (start > mid) return getSum(node.right, start, end); if (end <= mid) return getSum(node.left, start, end); return getSum(node.left, start, mid) + getSum(node.right, mid + 1, end); } public int getSum(int start, int end) { return getSum(root, start, end); } public NumArray(int[] nums) { if (nums == null || nums.length == 0) return; this.nums = nums; this.root = build(0, nums.length - 1); } void update(int i, int val) { update(root, i, val); } public int sumRange(int i, int j) { return getSum(i, j); } } // Your NumArray object will be instantiated and called as such: // NumArray numArray = new NumArray(nums); // numArray.sumRange(0, 1); // numArray.update(1, 10); // numArray.sumRange(1, 2);
308. Range Sum Query 2D - Mutable
http://www.cnblogs.com/yrbbest/p/5058571.html

浙公网安备 33010602011771号