• 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;
        }
    }
    
  • 相关阅读:
    OJ练习31——T155 Min Stack
    OJ练习30——T125 Valid Palindrome
    OJ练习29——T119 Pascal's Triangle II
    最大公约数——414AMashmokh and Numbers
    数学——415B. Mashmokh and Tokens
    水题——415A. Mashmokh and Lights
    湖南大学2015年“新生杯”程序设计竞赛
    react的ES6写法
    【Ionic】ionic安装和项目的创建 及相关介绍
    Flex 弹性布局教程很不错
  • 原文地址:https://www.cnblogs.com/a1439775520/p/12946586.html
Copyright © 2020-2023  润新知