[路飞]leetcode-327. 区间和的个数

101 阅读1分钟

给你一个整数数组 nums 以及两个整数 lower 和 upper 。求数组中,值位于范围 [lower, upper] (包含 lower 和 upper)之内的 区间和的个数 。

区间和 S(i, j) 表示在 nums 中,位置从 i 到 j 的元素之和,包含 i 和 j (i ≤ j)。力扣原文

示例 1:

输入: nums = [-2,5,-1], lower = -2, upper = 2
输出: 3
解释: 存在三个区间:[0,0][2,2][0,2] ,对应的区间和分别是:-2 、-1 、2 。

示例 2:

输入: nums = [0], lower = 0, upper = 0
输出: 1

解题:

let temp=[]
var countRangeSum = function(nums, lower, upper) {
    let sum=[0]
    for (let i = 0; i < nums.length; i++) {
        sum[i+1]=sum[i]+nums[i]
        
    }
    return margeSort(sum,0,sum.length-1,lower, upper)
};
var margeSort = function(sum,left,right, lower, upper) {
    if(left>=right)return 0
    let mid=(left+right)>>1,ans=0
    ans+=margeSort(sum,left,mid,lower, upper)
    ans+=margeSort(sum,mid+1 ,right,lower, upper)
    let start=left,end=left;
    for(let j=mid+1;j<=right;j++){
        const min=sum[j]-upper
        const max=sum[j]-lower
        while(sum[start]<min&&start<=mid)start++
        while(sum[end]<=max&&end<=mid)end++
        ans+=(end-start)
    }
    temp=[]
    let k=left,l=left,r=mid+1
    while(l<=mid || r<=right){
        if((r>right)||(l<=mid&&sum[l]<=sum[r])){
            temp[k++]=sum[l++]
        }else{
            temp[k++]=sum[r++]
        }
    }
    for (let i = left; i <=right; i++) {
        sum[i]=temp[i]
        
    }
    return ans
}