Java实现 LeetCode 327 区间和的个数

327. 区间和的个数

给定一个整数数组 nums,返回区间和在 [lower, upper] 之间的个数,包含 lower 和 upper。
区间和 S(i, j) 表示在 nums 中,位置从 i 到 j 的元素之和,包含 i 和 j (i ≤ j)。

说明:
最直观的算法复杂度是 O(n2) ,请在此基础上优化你的算法。

示例:

输入: nums = [-2,5,-1], lower = -2, upper = 2,
输出: 3
解释: 3个区间分别是: [0,0], [2,2], [0,2],它们表示的和分别为: -2, -1, 2。

class Solution {
   public int countRangeSum(int[] nums, long lower, long upper) {
        long sums[] = new long[nums.length];
        for (int i=0; i<nums.length; i++) {
            sums[i] = ((i-1 >= 0) ? sums[i-1] : 0) + nums[i];
        }
        //System.out.println(Arrays.toString(sums));
        int result = divideAndConquer(sums, 0, sums.length-1, upper, lower);

        return result;
    }

    private int divideAndConquer(long sums[], int start, int end, long upper, long lower) {
        if (start > end) return 0;
        if (start == end) return (sums[start] <= upper && sums[start] >= lower) ? 1 : 0;
        int mid = (start+end)/2;
        int counts = 0;
        counts += divideAndConquer(sums, start, mid, upper, lower);
        counts += divideAndConquer(sums, mid+1, end, upper, lower);

        int ls = start, le=mid;
        while (le >= start && sums[mid+1] - sums[le] <= upper) le--;
        for (int r=mid+1; r<=end; r++) {
            while (ls <= mid && sums[r] - sums[ls] >= lower) ls++;
            while (le+1 <= mid && sums[r] - sums[le+1] > upper ) le++;
            if (ls - le -1 < 0) continue;
            counts += (ls-le-1);
        }
        ls = start;
        int i = 0, r= mid+1;
        long merged[] = new long[end-start+1];
        while (ls <= mid || r <= end) {
            if (ls > mid || (r<=end && sums[r] < sums[ls])) {
                merged[i++] = sums[r++];
            } else {
                merged[i++] = sums[ls++];
            }
        }
        for (i=0; i<merged.length; i++) {
            sums[start+i] = merged[i];
        }
        //System.out.println(Arrays.toString(sums) + " "  + counts + "," + start + "-" + end);
        return counts;
    }
}
发布了1440 篇原创文章 · 获赞 1万+ · 访问量 164万+

猜你喜欢

转载自blog.csdn.net/a1439775520/article/details/104706672