327 Count of Range Sum

1. Question

Given an integer arraynums, return the number of range sums that lie in[lower, upper]inclusive. Range sumS(i, j)is defined as the sum of the elements innumsbetween indicesiandj(ij), inclusive.

Note: A naive algorithm of O(n^2) is trivial. You MUST do better than that.

Example: Givennums=[-2, 5, -1],lower=-2,upper=2, Return3. The three ranges are :[0, 0],[2, 2],[0, 2]and their respective sums are:-2, -1, 2.

2. Implementation

(1) TreeMap

我们定义sum[i]为nums[0...i]之间的subarray sum, 对于区间[j,i]的subarray sum,其值等于sum[i] - sum[j], 如果 lower <= sum[i] - sum[j] <= upper, 通过推导可以得出 sum[j] - upper <= sum[j] <= sum[i] - lower. 我们遍历数组的时候,利用sum变量加上当前的数,这样我们很容易得到sum[i], 要得到sum[j], 我们利用TreeMap的区间查询的特性,查询treemap,key在 sum[i] - upper[i] 和 sum[i] - lower之间的值的个数,最后得到结果

public class Solution {
    public int countRangeSum(int[] nums, int lower, int upper) {        
        TreeMap<Long, Long> map = new TreeMap();
        map.put((long)0, (long)1);
        long sum = 0;
        int count = 0;
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
            long fromKey = sum - upper;
            long toKey = sum - lower;
            Map<Long, Long> subMap = map.subMap(fromKey, true, toKey, true);

            for (long value : subMap.values()) {
                count += value;
            }

            if (map.containsKey(sum)) {
                map.put(sum, map.get(sum) + 1);
            }
            else {
                map.put(sum, (long)1);
            }
        }
        return count;
    }
}

(2) Merge Sort

思路: 这里的思路和Leetcode 315很类似,我们利用merge sort,在merge的过程中count 符合条件的区间和个数. 具体在我们的merge()里,我们知道sum[start, mid] 和 sum[mid + 1, end]这两个区间是已经排好序的,对于每个在左区间的数sum[left], 我们分别要找出一个index high满足sum[high] - sum[left] > upper, 以及第一个index low满足sum[low] - sum[left] >= lower, 这样符合条件的区间个数就是 high - low. 在计算符合条件的区间个数同时,我们也顺便完成merge的过程

(3) Segment Tree

3. Time & Space Complexity

TreeMap: 时间复杂度O(nlogn), 空间复杂度O(n)

Merge Sort: 时间复杂度O(nlogn), 空间复杂度O(n)

Last updated

Was this helpful?