• LeetCode Count of Range Sum


    原题链接在这里:https://leetcode.com/problems/count-of-range-sum/

    题目:

    Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.
    Range sum S(i, j) is defined as the sum of the elements in nums between indices i and j (i ≤ j), inclusive.

    Note:
    A naive algorithm of O(n2) is trivial. You MUST do better than that.

    Example:
    Given nums = [-2, 5, -1]lower = -2upper = 2,
    Return 3.
    The three ranges are : [0, 0][2, 2][0, 2] and their respective sums are: -2, -1, 2.

    题解:

    题目的意思是说给了一个int array, 计算有多少subarray的sum在[lower, upper]区间内. 给的例子是index.

    建立BST,每个TreeNode的val是prefix sum. 为了避免重复的TreeNode.val, 设置一个count记录多少个重复TreeNode.val, 维护leftSize, 记录比该节点value小的节点个数,rightSize同理.

    由于RangeSum S(i,j)在[lower,upper]之间的条件是lower<=sums[j+1]-sums[i]<=upper. 所以我们每次insert一个新的PrefixSum sums[k]进这个BST之前,先寻找一下rangeSize该BST内已经有多少个PrefixSum, 叫它sums[t]吧, 满足lower<=sums[k]-sums[t]<=upper, 即寻找有多少个sums[t]满足: 

    sums[k]-upper<=sums[t]<=sums[k]-lower

    BST提供了countSmaller和countLarger的功能,计算比sums[k]-upper小的RangeSum数目和比sums[k]-lower大的数目,再从总数里面减去,就是所求

    Time Complexity: O(nlogn). Space: O(n).

    AC Java:

     1 public class Solution {
     2     public int countRangeSum(int[] nums, int lower, int upper) {
     3         if(nums == null || nums.length == 0){
     4             return 0;
     5         }
     6         int res = 0;
     7         long [] sum = new long[nums.length+1];
     8         for(int i = 1; i<sum.length; i++){
     9             sum[i] = sum[i-1] + nums[i-1];
    10         }
    11         
    12         TreeNode root = new TreeNode(sum[0]);
    13         for(int i = 1; i<sum.length; i++){
    14             res += rangeSize(root, sum[i]-upper, sum[i]-lower);
    15             insert(root, sum[i]);
    16         }
    17         return res;
    18     }
    19     
    20     private TreeNode insert(TreeNode root, long val){
    21         if(root == null){
    22             return new TreeNode(val);
    23         }
    24         if(root.val == val){
    25             root.count++;
    26         }else if(root.val > val){
    27             root.leftSize++;
    28             root.left = insert(root.left, val);
    29         }else if(root.val < val){
    30             root.rightSize++;
    31             root.right = insert(root.right, val);
    32         }
    33         return root;
    34     }
    35     
    36     private int countSmaller(TreeNode root, long val){
    37         if(root == null){
    38             return 0;
    39         }
    40         if(root.val == val){
    41             return root.leftSize;
    42         }else if(root.val > val){
    43             return countSmaller(root.left, val);
    44         }else{
    45             return root.leftSize + root.count + countSmaller(root.right, val);
    46         }
    47     }
    48     
    49     private int countLarget(TreeNode root, long val){
    50         if(root == null){
    51             return 0;
    52         }
    53         if(root.val == val){
    54             return root.rightSize;
    55         }else if(root.val > val){
    56             return countLarget(root.left, val) + root.count + root.rightSize;
    57         }else{
    58             return countLarget(root.right, val);
    59         }
    60     }
    61     
    62     private int rangeSize(TreeNode root, long lower, long upper){
    63         int total = root.leftSize + root.count + root.rightSize;
    64         int smaller = countSmaller(root, lower);
    65         int larger = countLarget(root, upper);
    66         return total - smaller - larger;
    67     }
    68 }
    69 
    70 class TreeNode{
    71     long val;
    72     int count;
    73     int leftSize;
    74     int rightSize;
    75     TreeNode left;
    76     TreeNode right;
    77     public TreeNode(long val){
    78         this.val = val;
    79         this.count = 1;
    80         this.leftSize = 0;
    81         this.rightSize = 0;
    82     }
    83 }

    Reference: http://www.cnblogs.com/EdwardLiu/p/5138198.html

  • 相关阅读:
    MySQL修改表中字段的字符集
    JMM内存模型相关笔记整理
    可重入锁与不可重入锁
    ForkJoin、并行流计算、串行流计算对比
    CyclicBarrier的用法
    git笔记整理-learnGitBranching
    Git 学习相关笔记
    《0day2》学习笔记-part5(书目第十二章(上))
    《0day2》学习笔记-part4(书目第八、九、十、十一章)
    《0day2》学习笔记-part3(书目第六、七章)
  • 原文地址:https://www.cnblogs.com/Dylan-Java-NYC/p/5321861.html
Copyright © 2020-2023  润新知