https://leetcode.com/problems/count-of-range-sum/
求和用long
解法一:
归并排序,同时计数
public class Solution {
public int countRangeSum(int[] nums, int lower, int upper) {
if (nums == null || nums.length == 0) {
return 0;
}
int len = nums.length;
long[] sum = new long[len + 1];
for (int i = 0; i < len; i++) {
sum[i + 1] = sum[i] + nums[i];
}
return mergeAndCount(sum, 0, len + 1, lower, upper);
}
private int mergeAndCount(long[] sum, int beg, int end, int lower, int upper) {
if (end - beg <= 1) {
return 0;
}
int mid = beg + (end - beg) / 2;
// 归并排序的同时进行计数。递归保证了beg~mid和mid~end已经分别有序。而[i, j]的部分和等于sum[j] - sum[i] && j > i
// 这样可以遍历mid~end找到在beg~mid之中特定i位置对应mid~end之中的上下界
int count = mergeAndCount(sum, beg, mid, lower, upper) + mergeAndCount(sum, mid, end, lower, upper);
int j = mid;
int k = mid;
int t = mid;
long[] cache = new long[end - beg];
for (int i = beg, r = 0; i < mid; i++, r++) {
while (j < end && sum[j] - sum[i] < lower) j++;
while (k < end && sum[k] - sum[i] <= upper) k++;
while (t < end && sum[t] < sum[i]) cache[r++] = sum[t++];
cache[r] = sum[i];
count += k - j;
}
// 当前需要归并排序的是sum之中beg~end的部分,t之后的位置已经是有序的,并且均比nums[mid - 1]更大,所以不再需要copy。
// cache之中是已经排序好的剩余部分
System.arraycopy(cache, 0, sum, beg, t - beg);
return count;
}
}
解法二:
线段树&树状数组
待解...