zoukankan      html  css  js  c++  java
  • 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

     [暴力解法]:

    时间分析:

    空间分析:

     [优化后]:

    时间分析:

    空间分析:

    [奇葩输出条件]:

    [奇葩corner case]:

    1.  buildSegmentTree时,start > end,没有区间,不能build;相等时 求和直接赋值
    2. updateSegmentTree时,start == end,就只有一个点,该点值为val。
    3. 求sumRange时,表示到头了,可以直接返回root.sum。针对来求和,参数应该是root的左右区间。
      root.end == end && root.start == start

    [思维问题]:

     buildSegmentTree是基于数组的,sumRange是基于树的,所以都要新建函数 (函数名一样 参数不一样)

    [英文数据结构或算法,为什么不用别的数据结构或算法]:

    [一句话思路]:

    从节点类开始,必须要有函数,把树新建起来

    buildTree

    [输入量]:空: 正常情况:特大:特小:程序里处理到的特殊情况:异常情况(不合法不合理的输入):

    [画图]:

    [一刷]:

    1. ret.sum要用左右节点的sum值更新 (通用的函数一般换一个名称 不直接用调用的名称)
    ret.sum = ret.left.sum + ret.right.sum;
    1. update时,dc分为在左子树更新&在右子树更新
    update(root.left, pos, val);
    1. 求和时,有三种情况。

    [二刷]:

    1. root新建为空,buildtree的函数在外层

    [三刷]:

    1. 树返回的是Node, 左右子树都要重建 需要分类讨论
    2. update函数是根据插入位置pos和mid的关系来划分的 非左即右用的是if else

    [四刷]:

    [五刷]:

      [五分钟肉眼debug的结果]:

    [总结]:

    [复杂度]:Time complexity: O(新建n 增加和删除是lgn) Space complexity: O(n)

    [算法思想:迭代/递归/分治/贪心]:

    分治

    [关键模板化代码]:

    [其他解法]:

    [Follow Up]:

    [LC给出的题目变变变]:

     [代码风格] :

     [是否头一次写此类driver funcion的代码] :

    1.  public static void main (String[] args)方法在整个类里面
    2. root是动态变量,不能被当作静态值传输
    // Java program to find largest rectangle with all 1s
    // in a binary matrix
    import java.io.*;
    import java.util.*;
    
    class NumArray {
        class segmentTreeNode{
            int start, end;
            segmentTreeNode left, right;
            int sum;
            
            public segmentTreeNode(int start, int end) {
                this.start = start;
                this.end = end;
                this.left = null;
                this.right = null;
                this.sum = 0;
            }
    }
    
        //root
        segmentTreeNode root = null;
    
        public NumArray(int[] nums) {
            root = buildTree(nums, 0, nums.length - 1);
        }
    
        public segmentTreeNode buildTree(int[] nums, int start, int end) {
            //cc
            if (start > end) return null;
            else {
                segmentTreeNode root = new segmentTreeNode(start, end);
                if (start == end) root.sum = nums[start];
                else {
                    int mid = start + (end - start) / 2;
                    root.left = buildTree(nums, start, mid);
                    root.right = buildTree(nums, mid + 1, end);
                    root.sum = root.left.sum + root.right.sum;
                }
                return root;
            }   
        }
        
        public void update(int i, int val) {
            update(root, i, val);
        }
        
        public void update(segmentTreeNode root, int pos, int val) {
            //cc change expression
            if (root.start == root.end) root.sum = val;
            else {
                int mid = root.start + (root.end - root.start) / 2;
                if (pos <= mid) {
                    update(root.left, pos, val);
                }
                else {
                    update(root.right, pos, val);
                }
                root.sum = root.left.sum + root.right.sum;
            }
        }
    
        public int sumRange(int i, int j) {
            return sumRange(root, i, j);
        }
    
        public int sumRange(segmentTreeNode root, int start, int end) {
            //cc
            if (root.start == start && root.end == end) return root.sum;
            else {
                int mid = root.start + (root.end - root.start) / 2;
                if (end <= mid) return sumRange(root.left, start, end);
                else if (start >= mid + 1) return sumRange(root.right, start, end);
                else return sumRange(root.left, start, mid) + sumRange(root.right, mid + 1, end);
            }
        }
      // Driver code
      public static void main (String[] args) 
      {
          
        int[] nums = {1, 3, 5};
        
        int start = 0, end = 2;
        segmentTreeNode root = new segmentTreeNode(start, end);
        //System.out.println("sumRange(start, end) is " + 
        //             sumRange(start, end));
        System.out.println("executed");
      }
    }
      
      
    
    
    // Contributed by Prakriti Gupta
    View Code
  • 相关阅读:
    【BZOJ3670】【NOI2014】动物园(KMP算法)
    【BZOJ4372】烁烁的游戏(动态点分治)
    【BZOJ3730】震波(动态点分治)
    【BZOJ3924】幻想乡战略游戏(动态点分治)
    【BZOJ1095】捉迷藏(动态点分治)
    动态点分治
    【BZOJ2333】棘手的操作(左偏树,STL)
    【BZOJ4816】数字表格(莫比乌斯反演)
    【BZOJ3506】排序机械臂(Splay)
    【BZOJ2693】jzptab(莫比乌斯反演)
  • 原文地址:https://www.cnblogs.com/immiao0319/p/9190026.html
Copyright © 2011-2022 走看看