LeetCode-Count of Range Sum

LiBlog發表於2016-08-11

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 (ij), inclusive.

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

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

Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.

Analysis:

See this post: http://huntzhan.org/leetcode-count-of-range-sum/

Solution:

Divide and Conquer O(nlogn)

 1 public class Solution {
 2    public int countRangeSum(int[] nums, int lower, int upper) {
 3         if (nums.length==0) return 0;
 4         
 5         long[] sums = new long[nums.length];
 6         long sum = 0;
 7         for (int i=0;i<nums.length;i++){
 8             sum += nums[i];
 9             sums[i] = sum;
10         }
11         
12         int res = countRangeSumRecur(sums,0,sums.length-1,lower,upper);
13         
14         return res;
15     }
16     
17     public int countRangeSumRecur(long[] sums, int start, int end, int lower, int upper){
18         if (start==end){
19             return (sums[start]>=lower && sums[start]<=upper) ? 1 : 0;
20         }
21         
22         int len = end-start+1;
23         long[] cache = new long[len];
24         int mid = (start+end)/2;
25         int leftCount = countRangeSumRecur(sums,start,mid,lower,upper);
26         int rightCount = countRangeSumRecur(sums,mid+1,end,lower,upper);
27         int res = leftCount + rightCount;
28         
29         // Count those cross left part and right part.
30         int l1 = start, r1 = mid+1, r2 = mid+1, i1=mid+1;
31         int ind = 0;
32         while (l1<mid+1){
33             // Get r1 and r2 into correct places.
34             while (r1<=end && sums[r1]-sums[l1]<lower) r1++;
35             while (r2<=end && sums[r2]-sums[l1]<=upper) r2++;
36             res += r2-r1;
37             
38             // Perform sorting work.
39             while (i1<=end && sums[i1]<=sums[l1]){
40                 cache[ind++] = sums[i1++];                
41             }
42             cache[ind++] = sums[l1];
43             l1++;
44         }
45         while (i1<=end){
46             cache[ind++] = sums[i1++];
47         }
48         
49         for (int i=0;i<len;i++){
50             sums[start+i] = cache[i];
51         }
52         
53         return res;
54     }
55 }

 

相關文章