照着人家的写了一个,原文解释的很详细了,稍微改了改。
public class Solution {
public int countRangeSum(int[] nums, int lower, int upper) {
if (nums == null || nums.length == 0) return 0;
long[] prefixSum = new long[nums.length];
prefixSum[0] = nums[0];
for (int i = 1; i < nums.length; i++) prefixSum[i] = prefixSum[i-1] + nums[i];
return mergeCount(prefixSum, 0, nums.length - 1, lower, upper);
}
private int mergeCount(long[] prefixSum, int start, int end, int lower, int upper) {
if (start == end) {
if (prefixSum[start] >= lower && prefixSum[start] <= upper) return 1;
else return 0;
}
int mid = (start + end) / 2;
int count = mergeCount(prefixSum, start, mid, lower, upper);
count += mergeCount(prefixSum, mid + 1, end, lower, upper);
long[] left = new long[mid - start + 1];
long[] right = new long[end - mid];
for (int i = 0; i < mid - start + 1; i++) left[i] = prefixSum[start + i];
for (int i = 0; i < end - mid; i++) right[i] = prefixSum[mid + 1 + i];
for (int leftIndex = 0, lowerBound = 0, upperBound = 0, rightIndex = 0, index = start; leftIndex < mid - start + 1; leftIndex++) {
while (lowerBound < end - mid && right[lowerBound] - left[leftIndex] < lower) lowerBound++;
while (upperBound < end - mid && right[upperBound] - left[leftIndex] <= upper) upperBound++;
count += upperBound - lowerBound;
while (rightIndex < end - mid && right[rightIndex] < left[leftIndex]) prefixSum[index++] = right[rightIndex++];
prefixSum[index++] = left[leftIndex];
}
return count;
}
}
No comments:
Post a Comment