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 }
  • 相关阅读:
    Ajax实现在textbox中输入内容,动态从数据库中模糊查询显示到下拉框中
    JavaScript 多级联动浮动(下拉)菜单 (第二版)
    JavaScript在IE浏览器和Firefox浏览器中的差异总结
    IE和FF对CSS兼容问题
    XHTML的特征(规范)
    总结引入CSS样式方式中的link和import的区别
    CSS知识精化集全,每天更新一点点,自己总结。
    今天遇见了setTimeout()函数
    jquery的发展由来和深入理解(一)
    左边导航条动态增加或缩短高度以及放大缩小问题的解决方法
  • 原文地址:https://www.cnblogs.com/liuliu5151/p/11397762.html
Copyright © 2011-2022 走看看