LeetCode327. 区间和的个数
LeetCode327. 区间和的个数
1 算法
- 算法
- 1.归并排序
- 2.计算前缀和sums[i]表示[0, i)的元素之和
- 3.对前缀和进行归并排序
- 首先将数组分成两半,递归对两个子数组进行归并排序,并将返回结果保存
- 这时两个子数组已经有序,可以统计这样的区间[x, y],x遍历左子数组,y遍历右子数组,求得sums[y] - sums[x]的值在[lower, upper]范围中的区间有多少个
- 最后需要将两个子数组合并成一个有序的数组
- 相似题目
2 Java
public int countRangeSum(int[] nums, int lower, int upper) {
if (nums == null || nums.length == 0) {
return 0;
}
long[] sums = new long[nums.length + 1];
for (int i = 1; i <= nums.length; i++) {
sums[i] = sums[i-1] + nums[i-1];
}
return countRangeSumRecursive(sums, lower, upper, 0, sums.length - 1);
}
private int countRangeSumRecursive(long[] sum, int lower, int upper, int left, int right) {
if (left == right) {
return 0;
} else {
int mid = (left + right) >> 1;
int n1 = countRangeSumRecursive(sum, lower, upper, left, mid);
int n2 = countRangeSumRecursive(sum, lower, upper, mid + 1, right);
int result = n1 + n2;
int l = mid + 1;
int r = mid + 1;
for (int i = left; i <= mid; i++) {
while (l <= right && sum[l] - sum[i] < lower) {
l++;
}
while (r <= right && sum[r] - sum[i] <= upper) {
r++;
}
result += r - l;
}
int[] sorted = new int[right - left + 1];
int p1 = left, p2 = mid + 1, i = 0;
while (p1 <= mid || p2 <= right) {
if (p1 > mid) {
sorted[i++] = (int) sum[p2++];
} else if (p2 > right) {
sorted[i++] = (int) sum[p1++];
} else {
if (sum[p1] < sum[p2]) {
sorted[i++] = (int) sum[p1++];
} else {
sorted[i++] = (int) sum[p2++];
}
}
}
System.arraycopy(sorted, 0, sum, left, sorted.length);
return result;
}
}
3 Go
func countRangeSum(nums []int, lower int, upper int) int {
if nums == nil || len(nums) == 0 {
return 0
}
sums := make([]int, len(nums) + 1)
for i := 1; i <= len(nums); i++ {
sums[i] = sums[i-1] + nums[i-1]
}
return countRangeSumRecursion(sums, lower, upper, 0, len(sums) - 1)
}
func countRangeSumRecursion(sums []int, lower, upper, left, right int) int {
if left == right {
return 0
} else {
mid := (left + right) >> 1
n1 := countRangeSumRecursion(sums, lower, upper, left, mid)
n2 := countRangeSumRecursion(sums, lower, upper, mid + 1, right)
result := n1 + n2
l, r := mid + 1, mid + 1
for i := left; i <= mid; i++ {
for l <= right && sums[l] - sums[i] < lower {
l++
}
for r <= right && sums[r] - sums[i] <= upper {
r++
}
result += r - l
}
sorted := make([]int, right - left + 1)
p1, p2, i := left, mid + 1, 0
for p1 <= mid || p2 <= right {
if p1 > mid {
sorted[i] = sums[p2]
p2++
} else if p2 > right {
sorted[i] = sums[p1]
p1++
} else {
if sums[p1] < sums[p2] {
sorted[i] = sums[p1]
p1++
} else {
sorted[i] = sums[p2]
p2++
}
}
i++
}
for k := 0; k < len(sorted); k++ {
sums[left + k] = sorted[k]
}
return result
}
}