题目描述:
给定一个整数数组 nums,返回区间和在 [lower, upper] 之间的个数,包含 lower 和 upper。
区间和 S(i, j) 表示在 nums 中,位置从 i 到 j 的元素之和,包含 i 和 j (i ≤ j)。
说明:
最直观的算法复杂度是 O(n2) ,请在此基础上优化你的算法。
思路:
参考官方题解
代码如下:
class Solution {
public:
int countRangeSumRevice(vector<long>&sum,int lower,int upper,int left,int right){
if(left==right){
return 0;
}
else{
int res=0;
int mid=left+(right-left)/2;
int n1=countRangeSumRevice(sum,lower,upper,left,mid);
int n2=countRangeSumRevice(sum,lower,upper,mid+1,right);
res=n1+n2;
//记录下标
int i=left;
int l=mid+1;
int r=mid+1;
while(i<=mid){
while(l<=right&&sum[l]-sum[i]<lower) l++;
while(r<=right&&sum[r]-sum[i]<=upper) r++;
res+=r-l;
i++;
}
//排列合并
vector<long>sorted(right-left+1);
int p1=left,p2=mid+1;
int p=0;
while(p1<=mid||p2<=right){
if(p1>mid){
sorted[p]=sum[p2];
p++;
p2++;
}
else if(p2>right){
sorted[p]=sum[p1];
p1++;
p++;
}
else{
if(sum[p1]<sum[p2]){
sorted[p]=sum[p1];
p++;
p1++;
}
else{
sorted[p]=sum[p2];
p++;
p2++;
}
}
}
for(int i=0;i<sorted.size();i++){
sum[left+i]=sorted[i];
}
return res;
}
}
int countRangeSum(vector<int>& nums, int lower, int upper) {
long s=0;
vector<long>sum={0};
for(auto& v:nums){
s+=v;
sum.push_back(s);
}
return countRangeSumRevice(sum,lower,upper,0,sum.size()-1);
}
};