/*
* 算法思想
* 使用归并排序的算法思想
* 1. 使用sums[i]数组放0->i-1的累加和,sums[0] = 0;
* 2. 对于任意的i!=j, lower <= sums[i]-sums[j] <= upper满足条件,则为一种可能的序列区间;
* 3. 对于有序的数组,取符合条件的返回,可使用双指针的方法。
*
*/
void print(long long *arr, int len){
int i=0;
for(i=0; i<len; i++){
printf("%d, ", arr[i]);
}
printf("\n");
}
/*
* merge two ordered arrays
*/
void merge(long long *sums, int start, int mid, int end){
long long buf[end-start+1];
int index=0, i=start, j=mid+1;
while(i<=mid && j<=end){
if(sums[i] < sums[j]){
buf[index++] = sums[i++];
}else{
buf[index++] = sums[j++];
}
}
while(i<=mid)
buf[index++] = sums[i++];
while(j<=end)
buf[index++] = sums[j++];
memcpy(sums+start, buf, sizeof(long long) * (index));
}
int merge_sort(long long *sums, int start, int end, long long l, long long u){
int mid, ret=0, i, m, n, ret1, ret2=0;
if(end - start < 1) return 0;
mid = (start + end) / 2;
m = mid+1;
n = mid+1;
/* sparate array to two parts, first part : [start, mid], second part: [mid+1, end]
* deal with [start, mid] , [mid+1, end] sparately */
ret1 = merge_sort(sums, start, mid, l, u) + merge_sort(sums, mid+1, end, l, u);
/* deal with current situation before merge operation;
* Notes:
* 1. on this condition, arr[start, mid] and arr[mid+1, end] are ordered increasingly;
* 2.
*/
for(i=start; i<=mid; i++){
while(m <= end && sums[m]-sums[i] < l)
m++;
while(n <= end && sums[n]-sums[i] <= u)
n++;
ret2 += (n-m);
}
merge(sums, start, mid, end);
ret = ret1 +ret2;
return ret;
}
int countRangeSum(int* ns, int len, int lower, int upper){
long long i, j, cnt=0;
if(!ns || !len) return 0;
long long sums[len+1], ret=0;
long long tmp;
sums[0] = 0;
for(i=0; i<len; i++){
cnt += ns[i];
sums[i+1] = cnt;
}
ret = merge_sort(sums, 0, len, lower, upper);
return ret ;
}
leetcode-327. 区间和的个数-C语言
最新推荐文章于 2022-05-25 20:30:46 发布