zoukankan      html  css  js  c++  java
  • 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;
        }
    }
    
  • 相关阅读:
    根据外键名找到主表和关联表的相关列
    MS SQL 查询未提交的事务和执行的SQL语句
    Ionic 的常见问题
    从零开始在linux上搭建web服务器
    bat 批量提取指定目录下的文件
    tornado 协程 和 多线程
    HTML认识二
    HTML标签认识一
    HTML认识一
    使用Mysql执行SQL语句基础操作
  • 原文地址:https://www.cnblogs.com/a1439775520/p/12946586.html
Copyright © 2011-2022 走看看