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;
}
相关推荐
剑心诀几秒前
02 数据结构(C) | 线性表——顺序表的基本操作
c语言·开发语言·数据结构
m0_4886333217 分钟前
Windows环境下编译运行C语言程序,合适工具与方法很关键
c语言·windows·git·开发工具·编译器
2501_9249526918 分钟前
代码生成器优化策略
开发语言·c++·算法
MORE_7723 分钟前
leecode100-划分区间-贪心算法
算法·贪心算法
Book思议-41 分钟前
【数据结构实战】C语言实现栈的链式存储:从初始化到销毁,手把手教你写可运行代码
数据结构·算法·链表··408
m0_4886333242 分钟前
C语言变量命名规则、入门自学、运算符优先级及数据结构介绍
c语言·数据结构·运算符优先级·变量命名·入门自学
Book思议-1 小时前
【数据结构实战】川剧 “扯脸” 与栈的 LIFO 特性 :用 C 语言实现 3 种栈结构
c语言·数据结构·算法·
3GPP仿真实验室1 小时前
【MATLAB源码】感知:CFAR 检测算法库
算法·matlab·目标跟踪
fengenrong1 小时前
20260324
c++·算法
qq_416018721 小时前
设计模式在C++中的实现
开发语言·c++·算法