zoukankan      html  css  js  c++  java
  • 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);
  • 相关阅读:
    《怎样解题》-波利亚
    BZOJ2631 tree
    BZOJ3669 [Noi2014]魔法森林
    BZOJ 2049 [Sdoi2008]Cave 洞穴勘测
    BZOJ2002 [Hnoi2010]Bounce 弹飞绵羊
    动态树入门
    树链剖分入门-Hdu3966 Aragorn's Story
    BZOJ1146 [CTSC2008]网络管理Network
    树的表示方法
    树状数组
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/5094610.html
Copyright © 2011-2022 走看看