您的位置:首页 > 其它

LeetCode 327. Count of Range Sum

2016-02-02 00:45 435 查看
无意看到的LeetCode新题,不算太简单,大意是给一个数组,询问多少区间和在某个[L,R]之内。首先做出前缀和,将问题转为数组中多少A[j]-A[i] (j>i)在范围内。

有一种基于归并排序的做法,在每次归并完左右两个子区间后,当前区间两部分分别都已经排序完毕,基于有序这一点,扫描后半段区间,对于每个A[i] (i>=mid),目标区间即为[ A[i]-R, A[i]-L ], 对于有序数组来说,求出元素落在某一区间的个数直接就是upper_bound-lower_bound,事实上,这里我们只需要另外两个浮动于前半段区间的指针即可动态维护upper_bound和lower_bound,因为查询目标区间的两个端点是不断递增的。

归并排序是以前抄自刘汝佳白书的左闭右开版,递归边界条件(只有一个数)做一下特判。另外LeetCode题目本身也需要注意许多边边角角的trick,比如输入vector为空,元素加加减减溢出的情况,所以直接无脑long long就好。

题外话,不知为何输出是一个int,按理如果卡O(n^2)的话,数据规模必然做到可以构造答案溢出int_max的。

class Solution {
public:
int lo,hi;
int ret=0;
void msort(vector<long long>& A,int x,int y,vector<long long>& T) {
if (y-x<=1) {
if (A[x]>=lo&&A[x]<=hi) ret++;
return;
}
int mid=x+(y-x)/2;

msort(A,x,mid,T);
msort(A,mid,y,T);
int p=x,q=mid,it=x;
int j1=x,j2=x;
for (int i=mid;i<y;i++) {
while (j1<mid&&A[i]-A[j1]>=lo)
j1++;
while (j2<mid&&A[i]-A[j2]>hi)
j2++;
ret+=j1-j2;
}
while (p<mid||q<y) {
if (q>=y||(p<mid&&A[p]<=A[q]))
T[it++]=A[p++];
else
T[it++]=A[q++];
}
for (int i=x; i<y; i++)
A[i]=T[i];
}
int countRangeSum(vector<int>& nums, int lower, int upper) {
if (nums.size()==0) return 0;
ret=0;
lo=lower,hi=upper;
vector<long long> temp(nums.size(),0);
vector<long long> vec;
vec.push_back(nums[0]);
for (int i=1;i<nums.size();i++)
vec.push_back(nums[i]+vec[i-1]);
msort(vec,0,vec.size(),temp);
return ret;
}
};


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: