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:
Input: nums = [-2,5,-1], lower = -2, upper = 2,
Output: 3
Explanation: The three ranges are : [0,0], [2,2], [0,2] and their respective sums are: -2, -1, 2.
classSolution {int lower, upper;publicintcountRangeSum(int[] nums,int lower,int upper) {long[] prefixSum =newlong[nums.length+1];this.lower= lower;this.upper= upper;// PrefixSum[i] -> Sum of first i elementsfor (int i =1; i <=nums.length; i++) prefixSum[i] = prefixSum[i -1] + nums[i -1];returnmergeSort(prefixSum,0,prefixSum.length-1); }privateintmergeSort(long[] prefixSum,int start,int end) {if (start >= end)return0;int mid = start + (end - start) /2;// The pairs in the left half and the pairs in the // right half get counted in the recursive calls.int leftAns =mergeSort(prefixSum, start, mid);int rightAns =mergeSort(prefixSum, mid +1, end);// We just need to also count the pairs that use both halves.return leftAns + rightAns +merge(prefixSum, start, end); }privateintmerge(long[] prefixSum,int start,int end) {int ans =0, mid = start + (end - start) /2;long[] temp =newlong[end - start +1];int pointer1 = start, pointer2 = mid +1, index =0;int left = mid +1, right = mid +1;// O(N), because "left" & "right" variables only move rightwhile (pointer1 <= mid) {// We find a limit, such that we just enter "lower" limitwhile (left <= end && prefixSum[left] - prefixSum[pointer1] < lower) left++;// We find a limit, such that we just get out of "upper" limitwhile (right <= end && prefixSum[right] - prefixSum[pointer1] <= upper) right++;// Normal merging processwhile (pointer2 <= end && prefixSum[pointer2] < prefixSum[pointer1]) temp[index++] = prefixSum[pointer2++]; temp[index++] = prefixSum[pointer1++];// Answer will be [L,R], L is shown by pointer1, & // R is shown by all the values in between [left,right) ans += right - left; }while (pointer2 <= end) temp[index++] = prefixSum[pointer2++];for (int i = start; i <= end; i++) prefixSum[i] = temp[i - start];return ans; }}