Leetcode: Range Sum Query

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.

Introduction of Segment Tree: http://www.geeksforgeeks.org/segment-tree-set-1-sum-of-given-range/

Time Complexity:
Time Complexity for tree construction is O(n). There are total 2n-1 nodes, and value of every node is calculated only once in tree construction.

Time complexity to query is O(Logn). To query a sum, we process at most four nodes at every level and number of levels is O(Logn).

The time complexity of update is also O(Logn). To update a leaf value, we process one node at every level and number of levels is O(Logn).

 1 public class NumArray {
 2     SegmentTreeNode root;
 3 
 4     public NumArray(int[] nums) {
 5         this.root = buildTree(nums, 0, nums.length-1);
 6     }
 7 
 8     void update(int i, int val) {
 9         update(root, i, val);
10     }
11 
12     public int sumRange(int i, int j) {
13         return sumRange(root, i, j);
14     }
15     
16     public SegmentTreeNode buildTree(int[] nums, int start, int end) {
17             if (start > end) return null;
18             else {
19                 SegmentTreeNode cur = new SegmentTreeNode(start, end);
20                 if (start == end) {
21                     cur.sum = nums[start];
22                 }
23                 else {
24                     int mid = start + (end - start)/2;
25                     cur.left = buildTree(nums, start, mid);
26                     cur.right = buildTree(nums, mid+1, end);
27                     cur.sum = cur.left.sum + cur.right.sum;
28                 }
29                 return cur;
30             }
31     }
32         
33     public void update(SegmentTreeNode root, int i, int val) {
34             if (root.start == root.end) { //leaf node
35                 root.sum = val;
36                 return;
37             }
38             else {
39                 int mid = root.start + (root.end - root.start)/2;
40                 if (i <= mid) update(root.left, i, val);
41                 else update(root.right, i, val);
42                 root.sum = root.left.sum + root.right.sum;
43             }
44     }
45         
46     public int sumRange(SegmentTreeNode root, int i, int j) {
47             if (i==root.start && j==root.end) return root.sum;
48             else {
49                 int mid = root.start + (root.end - root.start)/2;
50                 if (j <= mid) return sumRange(root.left, i, j);
51                 else if (i >= mid+1) return sumRange(root.right, i, j);
52                 else 
53                     return sumRange(root.left, i, mid) + sumRange(root.right, mid+1, j);
54             }
55     }
56         
57     
58     public class SegmentTreeNode{
59         int sum;
60         int start;
61         int end;
62         SegmentTreeNode left;
63         SegmentTreeNode right;
64         
65         public SegmentTreeNode(int start, int end) {
66             this.sum = 0;
67             this.start = start;
68             this.end = end;
69             this.left = null;
70             this.right = null;
71         }
72         
73     }
74 }
75 
76 
77 // Your NumArray object will be instantiated and called as such:
78 // NumArray numArray = new NumArray(nums);
79 // numArray.sumRange(0, 1);
80 // numArray.update(1, 10);
81 // numArray.sumRange(1, 2);
原文地址:https://www.cnblogs.com/EdwardLiu/p/5094610.html