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} <= numsi <= 2^{31} - 1 −231<=numsi<=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 prefixSumsi 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 prefixSumsj+1 - prefixSumsi.

  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;
}
相关推荐
kkeeper~3 分钟前
0基础C语言积跬步之自定义类型结构体
c语言·开发语言
weixin_4684668543 分钟前
支持向量机新手实战指南
人工智能·python·算法·机器学习·支持向量机
weixin_468466852 小时前
机器学习之决策树新手实战指南
人工智能·python·算法·决策树·机器学习·ai
wanghu20242 小时前
ABC460_E题题解
c++·算法
z200509302 小时前
今日算法(回溯子集)
数据结构·算法·leetcode
Hesionberger2 小时前
巧用异或找出唯一数字(多解)
java·数据结构·python·算法·leetcode
小何code2 小时前
C语言【初阶】第1节,初识C语言
c语言·开发语言
莫陌尛.2 小时前
Fuzzy C-Mean Clustering (FCM)
c语言·开发语言
变量未定义~2 小时前
阶乘的约数和、斐波那契数列、数列区间最大值(ST表)
数据结构·算法
智者知已应修善业2 小时前
【51单片机象棋快棋赛 电子裁判器】2023-12-27
c++·经验分享·笔记·算法·51单片机