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;
}
相关推荐
稚南城才子,乌衣巷风流36 分钟前
ST 表(Sparse Table)算法详解:原理、实现与应用
算法
hold?fish:palm42 分钟前
9 找到字符串中所有字母异位词
c++·算法·leetcode
Sw1zzle1 小时前
算法入门(六):贪心算法 - 基础入门(Leetcode 121/455/860/376/738)
算法·leetcode·贪心算法
青山木1 小时前
Hot 100 --- 岛屿数量
java·数据结构·算法·leetcode·深度优先·广度优先
不会就选b2 小时前
算法日常・每日刷题--<归并排序>1
数据结构·算法
危桥带雨2 小时前
排序算法(快排、归并、计数、基数排序)
数据结构·算法·排序算法
啦啦啦啦啦zzzz2 小时前
算法:回溯算法
c++·算法·leetcode
会飞的小新2 小时前
C 标准库之 <fenv.h> 详解与深度解析
c语言·开发语言·microsoft
IT探索2 小时前
Linux 查找文件指令总结
linux·算法