【LeetCode每日一题】[困难]327. 区间和的个数

【LeetCode每日一题】[困难]327. 区间和的个数

327. 区间和的个数

327. 区间和的个数

算法思想:数组,并归排序思想

题目:

在这里插入图片描述
思路: link
在这里插入图片描述
为什么可以排序??思路来源
在这里插入图片描述

java代码

class Solution {
    
    
    int count = 0;//区间和数量
	int lower;//下限
	int upper;//上限
	public int countRangeSum(int[] nums, int lower, int upper) {
    
    
		int n = nums.length;//数组长度
		this.lower = lower;
		this.upper = upper;
		long[] preSum = new long[n + 1];//用来统计i之前的数组元素之和
        //前序和
		preSum[0] = 0;
		for (int i = 0; i < n; i++) {
    
    
			preSum[i+1] = preSum[i] + nums[i];
		}
        //递归调用统计区间和数量
		countRangeMerge(preSum, 0, n);
		return count;
	}
	private void countRangeMerge(long[] preSum, int left, int right) {
    
    //[left,right]包括左右边界
		if (left == right) {
    
    //如果左右边界相同,表示没有元素,返回
			return;
		}
		
		//划分
		int mid = (left + right) / 2;//中间值
		countRangeMerge(preSum, left, mid);
		countRangeMerge(preSum, mid + 1, right);
		
		//计数
        int lowerIdx = mid + 1;//下限坐标
		int upperIdx = mid + 1;//上限坐标
		for (int i = left; i <= mid; i++) {
    
    
			while (lowerIdx <= right && preSum[lowerIdx] - preSum[i] < lower) {
    
    
				lowerIdx++;//向右寻找最小下限坐标
			}
			while (upperIdx <= right && preSum[upperIdx] - preSum[i] <= upper) {
    
    
				upperIdx++;//向右寻找最大上限坐标
			}
			count += upperIdx - lowerIdx;//统计区间个数
		}
		
		//合并两个有序数组,使preSum在区间[left,right]有序
		long[] merge = new long[right - left + 1];
		int i = left;
		int j = mid + 1;
		int k = 0;
		while (i <= mid && j <= right) {
    
    
			if (preSum[i] <= preSum[j]) {
    
    
				merge[k++] = preSum[i++];
			}
			else {
    
    
				merge[k++] = preSum[j++];
			}
		}
		while (i <= mid) {
    
    
			merge[k++] = preSum[i++];
		}
		while (j <= right) {
    
    
			merge[k++] = preSum[j++];
		}
		for (int k2 = 0; k2 < merge.length; k2++) {
    
    
			preSum[left + k2] = merge[k2];
		}
	}
}

猜你喜欢

转载自blog.csdn.net/qq_39457586/article/details/109675544