LeetCode //C - 327. Count of Range Sum

327. Count of Range Sum

Given an integer array nums and two integers lower and upper, return the number of range sums that lie in [lower, upper] inclusive.

Range sum S(i, j) is defined as the sum of the elements in nums between indices i and j inclusive, where i <= j.

Example 1:

Input: nums = [-2,5,-1], lower = -2, upper = 2
Output: 3
Explanation: The three ranges are: [0,0], [2,2], and [0,2] and their respective sums are: -2, -1, 2.

Example 2:

Input: nums = [0], lower = 0, upper = 0
Output: 1

Constraints:
  • 1 < = n u m s . l e n g t h < = 1 0 5 1 <= nums.length <= 10^5 1<=nums.length<=105
  • − 2 31 < = n u m s [ i ] < = 2 31 − 1 -2^{31} <= nums[i] <= 2^{31} - 1 −231<=nums[i]<=231−1
  • − 1 0 5 < = l o w e r < = u p p e r < = 1 0 5 -10^5 <= lower <= upper <= 10^5 −105<=lower<=upper<=105
  • The answer is guaranteed to fit in a 32-bit integer.

From: LeetCode

Link: 327. Count of Range Sum


Solution:

Ideas:
  1. Prefix Sum Array: We create a prefix sum array where prefixSums[i] represents the sum of the array elements from the start to the i-th index. This allows us to calculate the sum of any subarray [i, j] as prefixSums[j+1] - prefixSums[i].

  2. Merge Sort: The core idea of the solution is to use a modified merge sort. During the merge step, we count the number of valid ranges [i, j] that satisfy the condition lower <= S(i, j) <= upper. This is done by maintaining the order of the prefix sums while counting how many sums in the right half of the array fall within the desired range relative to each sum in the left half.

  3. Counting with Binary Search: Within the merge step, we use two pointers to determine the range [lower, upper] for each prefix sum in the left half compared to prefix sums in the right half. This ensures that the solution remains efficient even for large arrays.

Code:
c 复制代码
long* temp;

int mergeCount(long* prefixSums, int left, int right, int lower, int upper) {
    if (left >= right) {
        return 0;
    }
    
    int mid = left + (right - left) / 2;
    int count = mergeCount(prefixSums, left, mid, lower, upper) + mergeCount(prefixSums, mid + 1, right, lower, upper);
    
    int j = mid + 1, k = mid + 1, t = mid + 1;
    int r = 0;
    
    for (int i = left; i <= mid; ++i) {
        while (j <= right && prefixSums[j] - prefixSums[i] < lower) j++;
        while (k <= right && prefixSums[k] - prefixSums[i] <= upper) k++;
        while (t <= right && prefixSums[t] < prefixSums[i]) temp[r++] = prefixSums[t++];
        temp[r++] = prefixSums[i];
        count += k - j;
    }
    
    for (int i = 0; i < t - left; ++i) {
        prefixSums[left + i] = temp[i];
    }
    
    return count;
}

int countRangeSum(int* nums, int numsSize, int lower, int upper) {
    if (numsSize == 0) {
        return 0;
    }
    
    long* prefixSums = (long*)malloc((numsSize + 1) * sizeof(long));
    temp = (long*)malloc((numsSize + 1) * sizeof(long));
    
    prefixSums[0] = 0;
    for (int i = 0; i < numsSize; ++i) {
        prefixSums[i + 1] = prefixSums[i] + nums[i];
    }
    
    int result = mergeCount(prefixSums, 0, numsSize, lower, upper);
    
    free(prefixSums);
    free(temp);
    
    return result;
}
相关推荐
前端 贾公子4 分钟前
详解 LeetCode 第 242 题 - 有效的字母组
算法·leetcode·职场和发展
sofaraway139 分钟前
【多目标进化算法】 MOEA/D算法(知识点)
算法
pystraf31 分钟前
UOJ 228 基础数据结构练习题 Solution
数据结构·c++·算法·线段树
海底火旺40 分钟前
破解二维矩阵搜索难题:从暴力到最优的算法之旅
javascript·算法·面试
祁同伟.1 小时前
【数据结构 · 初阶】- 堆的实现
c语言·数据结构
夜夜敲码1 小时前
C语言教程(十六): C 语言字符串详解
c语言·开发语言
宋康1 小时前
C语言结构体和union内存对齐
c语言·开发语言
学习噢学个屁1 小时前
基于51单片机的超声波液位测量与控制系统
c语言·单片机·嵌入式硬件·51单片机
黄昏ivi2 小时前
电力系统最小惯性常数解析
算法
独家回忆3642 小时前
每日算法-250425
算法