Given an integer array nums, 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 (i ≤ j), inclusive.

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

Example:

Input: nums = [-2,5,-1], lower = -2, upper = 2,
Output: 3
Explanation: The three ranges are : [0,0], [2,2], [0,2] and their respective sums are: -2, -1, 2.

Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.

这道题给了我们一个数组,又给了一个下限和一个上限,让求有多少个不同的区间使得每个区间的和在给定的上下限之间。这道题的难度系数给的是 Hard,的确是一道难度不小的题,题目中也说了 Brute Force 的方法太 Naive 了,只能另想方法了。To be honest,这题超出了博主的能力范围,所以博主也没挣扎了,直接上网搜大神们的解法啦。首先根据前面的那几道类似题 Range Sum Query - MutableRange Sum Query 2D - Immutable 和 Range Sum Query - Immutable 的解法可知类似的区间和的问题一定是要计算累积和数组 sums 的,其中 sum[i] = nums[0] + nums[1] + ... + nums[i],对于某个i来说,只有那些满足 lower <= sum[i] - sum[j] <= upper 的j能形成一个区间 [j, i] 满足题意,目标就是来找到有多少个这样的 j (0 =< j < i) 满足 sum[i] - upper =< sum[j] <= sum[i] - lower,可以用 C++ 中由红黑树实现的 multiset 数据结构可以对其中数据排序,然后用 upperbound 和 lowerbound 来找临界值。lower_bound 是找数组中第一个不小于给定值的数(包括等于情况),而 upper_bound 是找数组中第一个大于给定值的数,那么两者相减,就是j的个数,参见代码如下:

解法一:

class Solution {
public:
int countRangeSum(vector<int>& nums, int lower, int upper) {
int res = ;
long long sum = ;
multiset<long long> sums;
sums.insert();
for (int i = ; i < nums.size(); ++i) {
sum += nums[i];
res += distance(sums.lower_bound(sum - upper), sums.upper_bound(sum - lower));
sums.insert(sum);
}
return res;
}
};

我们再来看一种方法,这种方法的思路和前一种一样,只是没有 STL 的 multiset 和 lower_bound 和 upper_bound 函数,而是使用了 Merge Sort 来解,在混合的过程中,已经给左半边 [start, mid) 和右半边 [mid, end) 排序了。当遍历左半边,对于每个i,需要在右半边找出k和j,使其满足:

j是第一个满足 sums[j] - sums[i] > upper 的下标

k是第一个满足 sums[k] - sums[i] >= lower 的下标

那么在 [lower, upper] 之间的区间的个数是 j - k,同时也需要另一个下标t,用来拷贝所有满足 sums[t] < sums[i] 到一个寄存器 Cache 中以完成混合排序的过程,这个步骤是混合排序的精髓所在,实际上这个寄存器的作用就是将 [start, end) 范围内的数字排好序先存到寄存器中,然后再覆盖原数组对应的位置即可,(注意这里 sums 可能会整型溢出,使用长整型 long 代替),参见代码如下:

解法二:

class Solution {
public:
int countRangeSum(vector<int>& nums, int lower, int upper) {
vector<long> sums(nums.size() + , );
for (int i = ; i < nums.size(); ++i) {
sums[i + ] = sums[i] + nums[i];
}
return countAndMergeSort(sums, , sums.size(), lower, upper);
}
int countAndMergeSort(vector<long>& sums, int start, int end, int lower, int upper) {
if (end - start <= ) return ;
int mid = start + (end - start) / ;
int cnt = countAndMergeSort(sums, start, mid, lower, upper) + countAndMergeSort(sums, mid, end, lower, upper);
int j = mid, k = mid, t = mid;
vector<int> cache(end - start, );
for (int i = start, r = ; i < mid; ++i, ++r) {
while (k < end && sums[k] - sums[i] < lower) ++k;
while (j < end && sums[j] - sums[i] <= upper) ++j;
while (t < end && sums[t] < sums[i]) cache[r++] = sums[t++];
cache[r] = sums[i];
cnt += j - k;
}
copy(cache.begin(), cache.begin() + t - start, sums.begin() + start);
return cnt;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/327

类似题目:

Range Sum Query - Mutable

Range Sum Query 2D - Immutable

Range Sum Query - Immutable

Reverse Pairs

Count of Smaller Numbers After Self

参考资料:

https://leetcode.com/problems/count-of-range-sum/

https://leetcode.com/problems/count-of-range-sum/discuss/77990/Share-my-solution

https://leetcode.com/problems/count-of-range-sum/discuss/78006/Summary-of-the-Divide-and-Conquer-based-and-Binary-Indexed-Tree-based-solutions

https://leetcode.com/problems/count-of-range-sum/discuss/78030/8-line-multiset-C%2B%2B-solution-(100ms)-also-binary-search-tree-(180ms)-%2B-mergesort(52ms)

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] 327. Count of Range Sum 区间和计数的更多相关文章

  1. 327 Count of Range Sum 区间和计数

    Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...

  2. 【算法之美】你可能想不到的归并排序的神奇应用 — leetcode 327. Count of Range Sum

    又是一道有意思的题目,Count of Range Sum.(PS:leetcode 我已经做了 190 道,欢迎围观全部题解 https://github.com/hanzichi/leetcode ...

  3. [LeetCode] Count of Range Sum 区间和计数

    Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...

  4. leetcode@ [327] Count of Range Sum (Binary Search)

    https://leetcode.com/problems/count-of-range-sum/ Given an integer array nums, return the number of ...

  5. LeetCode 327. Count of Range Sum

    无意看到的LeetCode新题,不算太简单,大意是给一个数组,询问多少区间和在某个[L,R]之内.首先做出前缀和,将问题转为数组中多少A[j]-A[i] (j>i)在范围内. 有一种基于归并排序 ...

  6. 327. Count of Range Sum

    /* * 327. Count of Range Sum * 2016-7-8 by Mingyang */ public int countRangeSum(int[] nums, int lowe ...

  7. 【LeetCode】327. Count of Range Sum

    题目: Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusiv ...

  8. 327. Count of Range Sum(inplace_marge)

    Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...

  9. LeetCode Count of Range Sum

    原题链接在这里:https://leetcode.com/problems/count-of-range-sum/ 题目: Given an integer array nums, return th ...

随机推荐

  1. pixijs shader贴图扫光效果

    pixijs shader贴图扫光效果 直接贴代码 const app = new PIXI.Application({ transparent: true }); document.body.app ...

  2. powershell玩转iis网站服务器

    1 ------------安装------------------ for win7,win8,win8.1,win10控制面板--->程序和功能--->开启关闭windows功能--- ...

  3. nginx的6种负载均衡策略

    在服务器集群中,Nginx起到一个反向代理服务器的作用.为了避免单独一个服务器压力过大导致服务器奔溃,就需要将不同用户的请求转发给不同给不同的服务器,保证集群中的每一台服务器都能正常运作,这种机制就叫 ...

  4. 小记 .NET Core 3.0 下 WPF 是如何运行的

    1. 解决方案架构 如图: 2. 生成的代码 如图: /// <summary> /// App /// </summary> public partial class App ...

  5. Serverless 的喧哗与骚动(一)附Serverless行业发展回顾

    作者 | 阿里中间件高级技术专家 许晓斌 <Maven实战>作者,曾负责 AliExpress 微服务架构演进,现在负责阿里集团 Serverless 技术研发落地. 导读:从 2016 ...

  6. Logstash:多个配置文件(conf)

    Logstash:多个配置文件(conf) 对于多个配置的处理方法,有多个处理方法: 多个pipeline 一个pipleline处理多个配置文件 一个pipeline含有一个逻辑的数据流,它从inp ...

  7. IOC : Unity 配置和使用

    原文出自:IOC : Unity 配置和使用 之前Terry Lee 已经介绍过Unity的简单使用了,不过那篇文章是针对旧版本的,现在的版本1.2版略有不同. 我下载了Unity并做了一个简单的测试 ...

  8. Oracle 11g 手工建库

    假设数据库软件已经安装好,现在没有图形界面无法用dbca安装数据库,那么用手工建库,数据库名为edw 创建目录 [oracle@localhost ~]$ mkdir -p /u01/app/orac ...

  9. liteos错误处理(十一)

    1. 概述 1.1 基本概念 错误处理指用户代码发生错误时,系统调用错误处理模块的接口函数,完成上报错误信息,并调用用户自己的钩子函数,进行特定的处理. 错误处理模块实现OS内部错误码记录功能.OS内 ...

  10. Placeholder_2:0 is both fed and fetched

    Placeholder_2:0 is both fed and fetched TensorFlow出现这个错误是因为网络的输入被原样输出,也就是说同一个东西既被输入网络,又被输出网络.