[LeetCode una pregunta por día] [Dificultad] 327. El número de sumas de intervalo

[LeetCode una pregunta por día] [Dificultad] 327. El número de sumas de intervalo

327. Número de sumas de intervalo

327. Número de sumas de intervalo

Idea de algoritmo: idea de matriz y ordenación

tema:

Inserte la descripción de la imagen aquí
Idea: ¿Por qué se pueden ordenar los enlaces
Inserte la descripción de la imagen aquí
? Fuente de ideas
Inserte la descripción de la imagen aquí

código 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];
		}
	}
}

Supongo que te gusta

Origin blog.csdn.net/qq_39457586/article/details/109675544
Recomendado
Clasificación