zoukankan      html  css  js  c++  java
  • [Leetcode]307. 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:

    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 }
  • 相关阅读:
    HDU 5640 King's Cake
    HDU 5615 Jam's math problem
    HDU 5610 Baby Ming and Weight lifting
    WHU1604 Play Apple 简单博弈
    HDU 1551 Cable master 二分
    CodeForces659C Tanya and Toys map
    Codeforces 960E 树dp
    gym 101485E 二分匹配
    Codeforces 961E 树状数组,思维
    Codeforces Round #473 (Div. 2) D 数学,贪心 F 线性基,模板
  • 原文地址:https://www.cnblogs.com/liuliu5151/p/11397762.html
Copyright © 2011-2022 走看看