第7天--算法(区间和的个数)
1.leetCode 327题
给你一个整数数组 nums 以及两个整数 lower 和 upper 。求数组中,值位于范围 [lower, upper] (包含 lower 和 upper)之内的 区间和的个数 。
区间和 S(i, j) 表示在 nums 中,位置从 i 到 j 的元素之和,包含 i 和 j (i ≤ j)。
class Solution {
public int countRangeSum(int[] nums, int lower, int upper) {
long sum[] = new long[nums.length];
long res = 0;
for(int i = 0;i < nums.length;i ++) {
res += nums[i];
sum[i] = res;
}
return mergeSort(sum,0,sum.length - 1,lower,upper);
}
public int mergeSort(long arr[],int left,int right,int lower,int upper) {
if(left == right) {
if(arr[left] >= lower && arr[left] <= upper) {
return 1;
}else {
return 0;
}
}
int mid = (left + right) >> 1;
return mergeSort(arr,left,mid,lower,upper) + mergeSort(arr,mid + 1,right,lower,upper) + merge(arr,left,mid,right,lower,upper);
}
public int merge(long arr[],int left,int mid,int right,int lower,int upper) {
int ans = 0;
int windowL = left;
int windowR = left;
for(int i = mid + 1;i <= right;i ++) {
long min = arr[i] - upper;
long max = arr[i] - lower;
while(windowL <= mid && arr[windowL] < min) {
windowL ++;
}
while(windowR <= mid && arr[windowR] <= max) {
windowR ++;
}
ans += windowR - windowL;
}
int s1 = left;
int s2 = mid + 1;
int i = 0;
long temp[] = new long[right - left + 1];
while(s1 <= mid && s2 <= right) {
if(arr[s1] <= arr[s2]) {
temp[i ++] = arr[s1 ++];
}else{
temp[i ++] = arr[s2 ++];
}
}
while(s1 <= mid) {
temp[i ++] = arr[s1 ++];
}
while(s2 <= right) {
temp[i ++] = arr[s2 ++];
}
for(int j = 0;j < temp.length;j ++) {
arr[left + j] = temp[j];
}
return ans;
}
}

浙公网安备 33010602011771号