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

    下面是二分索引树,该树要注意一点,就是下标从1开始的,代码如下:

     1 public class NumArray {
     2     int[] BIT;
     3     int[] nums;
     4     int len;
     5     public NumArray(int[] nums) {
     6         len = nums.length;
     7         BIT = new int[len+1];
     8         this.nums = nums;
     9         for(int i=0;i<len;i++){
    10             init(i,nums[i]);
    11         }
    12     }
    13     public void init(int i,int val){
    14         i++;
    15         while(i<=len){
    16             BIT[i] += val;
    17             i+=(i&-i);
    18         }
    19     }
    20     
    21     public void update(int i, int val) {
    22         int diff = val-nums[i];
    23         nums[i] = val;
    24         init(i,diff);
    25     }
    26     public int getSum(int i){
    27         int sum = 0;
    28         i++;
    29         while(i>0){
    30             sum += BIT[i];
    31             i-=(i&-i);
    32         }
    33         return sum;
    34     }
    35     
    36     public int sumRange(int i, int j) {
    37         return getSum(j)-getSum(i-1);
    38     }
    39 }
    40 
    41 /**
    42  * Your NumArray object will be instantiated and called as such:
    43  * NumArray obj = new NumArray(nums);
    44  * obj.update(i,val);
    45  * int param_2 = obj.sumRange(i,j);
    46  */
  • 相关阅读:
    js压缩、混淆和加密 Alan
    与、或、异或运算 Alan
    Hello world Alan
    abstract class和interface有什么区别?
    接口是否可继承接口? 抽像类是否可实现(implements)接口? 抽像类是否可继承实体类(concrete class)?
    启动一个线程是用run()还是start()?
    数组有没有length()这个方法? String有没有length()这个方法?
    swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
    当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
    简要谈一下您对微软.NET 构架下remoting和webservice两项技术的理解以及实际中的应用。
  • 原文地址:https://www.cnblogs.com/codeskiller/p/6496523.html
Copyright © 2020-2023  润新知