程序媛詹妮弗
终身学习

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:

  1. The array is only modifiable by the update function.
  2. You may assume the number of calls to update and sumRange function is distributed evenly.

 

 

思路:

线段树

1. 将给定数组的信息转到线段树。 用recursion来build tree

2. 在建好的线段树上进行sumRange()操作, 时间复杂度为O(logn)

3. 在建好的线段树上进行update()操作, 时间复杂度为O(logn)

 

代码

 1 class NumArray {
 2     private SegmentTreeNode root;   
 3     /*Time Complexity: O(n)
 4       Build SegmentTree
 5      */
 6     public NumArray (int[] nums) {
 7         this.root = buildTree(nums, 0, nums.length - 1);
 8     }
 9     private SegmentTreeNode buildTree(int[] nums, int start, int end) {
10         if (start > end) return null;
11         SegmentTreeNode node = new SegmentTreeNode(start, end);
12         if (start == end) {
13             node.val = nums[start];
14         } else {
15             int mid = start + (end - start) / 2;
16             node.left = buildTree(nums, start, mid);
17             node.right = buildTree(nums, mid + 1, end);
18             node.val = node.left.val + node.right.val;
19         }
20         return node;    
21     }
22     /* Time Complexity: O(log n)
23        update()
24      */
25     public void update(int i, int val) {
26         update(this.root, i, val);
27     }
28     void update(SegmentTreeNode root, int i, int val) {
29         if (root.start == root.end) {
30             root.val = val;
31             return;
32         }
33         int middle = root.start + (root.end - root.start) / 2;
34         if (i <= middle) {
35             update(root.left, i, val);
36         } else {
37             update(root.right, i, val);
38         }
39         root.val = root.left.val + root.right.val;
40     }
41     /* Time Complexity: O(log n)
42        sumRange()
43      */
44     public int sumRange(int i, int j) {
45         return sumRange(this.root, i, j);
46     }
47     int sumRange(SegmentTreeNode root, int start, int end) {
48         if (root.end == end && root.start == start) return root.val;
49         int mid = root.start + (root.end - root.start) / 2;
50         if (end <= mid) {
51             return sumRange(root.left, start, end);
52         } else if (start >= mid + 1) {
53             return sumRange(root.right, start, end);
54         } else {
55             return sumRange(root.right, mid + 1, end) + sumRange(root.left, start, mid);
56         }
57     }
58 
59     class SegmentTreeNode {
60         int start;
61         int end;
62         int val;
63         SegmentTreeNode left;
64         SegmentTreeNode right;
65 
66         public SegmentTreeNode(int start, int end) {
67             this.start = start;
68             this.end = end;
69             this.val = 0;
70         }
71     }
72 }

 

posted on 2019-08-23 06:26  程序媛詹妮弗  阅读(253)  评论(0编辑  收藏  举报