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 = -2
, upper = 2
,
Return 3
.
The three ranges are : [0, 0]
, [2, 2]
, [0, 2]
and their respective sums are: -2, -1, 2
.
首先求出把数i的前面所有数的累加值数组,prefix_sums[i] , 那么S(i,j) = prefix_sums[j] - prefix_sums[i].
这样问题就可以简化为.
对于一个i,(0<i<n-1),找到有效的点(j>i)使得:
lower + prefix_sums[i] <= prefix_sums[j] <= upper + prefix_sums[i]
这样可以转化为一个Range Search 问题。
这个问题可以在O(log n + K)(K是在Range个数)利用二叉搜索树解决。
STL的multiset是利用二叉搜索树实现的。利用multiset 即可。
class Solution { public: int countRangeSum(vector<int>& nums, int lower, int upper) { multiset<long long> Set ; vector<long long> PreSum(nums.size()+1) ; long long sum = 0; PreSum[0] = 0; for(int i=0; i<nums.size(); ++i){ sum += nums[i]; PreSum[i+1] = sum; } int count = 0; for(int i=nums.size(); i>=1 ; --i){ Set.insert(PreSum[i]); auto lowbound = Set.lower_bound(PreSum[i-1]+lower); auto uppbound = Set.upper_bound(PreSum[i-1]+upper); count += distance(lowbound,uppbound); } return count; } };