[LeetCode] Count of Range Sum 区间和计数
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 - Mutable,Range 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 2D - Immutable
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
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Count of Range Sum 区间和计数的更多相关文章
- [LeetCode] 327. Count of Range Sum 区间和计数
Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...
- 327 Count of Range Sum 区间和计数
Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...
- LeetCode Count of Range Sum
原题链接在这里:https://leetcode.com/problems/count-of-range-sum/ 题目: Given an integer array nums, return th ...
- 【算法之美】你可能想不到的归并排序的神奇应用 — leetcode 327. Count of Range Sum
又是一道有意思的题目,Count of Range Sum.(PS:leetcode 我已经做了 190 道,欢迎围观全部题解 https://github.com/hanzichi/leetcode ...
- 327. Count of Range Sum
/* * 327. Count of Range Sum * 2016-7-8 by Mingyang */ public int countRangeSum(int[] nums, int lowe ...
- [Swift]LeetCode327. 区间和的个数 | Count of Range Sum
Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.Ra ...
- 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 ...
- 【LeetCode】327. Count of Range Sum
题目: Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusiv ...
- leetcode327 Count of Range Sum
问题描述: 给定一个整数数组nums,返回其所有落在[low, upper]范围内(包含边界)的区间和的数目. 区间和sums(i, j)的定义为所有下标为i到j之间(i ≤ j)的元素的和,包含边界 ...
随机推荐
- Javascript学习笔记1
一.写在前面的话 之前一直没有系统的学习javascript,自己也是小白,很多东西感觉不会,从本篇起,自己会抽出时间来,慢慢学习,好好领会! 深知学习是一个漫长的过程,来不得急躁,不积跬步,无以至千 ...
- java代码的初始化过程研究
刚刚在ITeye上看到一篇关于java代码初始化的文章,看到代码我试着推理了下结果,虽然是大学时代学的知识了,没想到还能做对.(看来自己大学时掌握的基础还算不错,(*^__^*) 嘻嘻……)但 ...
- CSS知识总结(一)
一.认识CSS 1.什么是CSS? CSS (Cascading Style Sheet) 层叠样式表 是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言. 由于CSS属性或规则尚未成为 ...
- [Servlet] 初识Servlet
什么是Servlet? 定义 Servlet的全称是 Server Applet,顾名思义,就是用 Java 编写的服务器端程序. Servlet 是一个 Java Web开发标准,狭义的Servle ...
- html+ccs3太阳系行星运转动画
做一个太阳系八大行星的运转动画,不包括行星的卫星,所有行星围绕太阳公转,行星采用纯色,暂时没有自转. 效果静态图: 动画中包括:太阳及各行星,运行轨道,行星公转动画. 先画好草图,设计好大小和位置,根 ...
- 判断IEnumerable<T>集合中是否包含有T对象
比如,有角色集合中,只有用户创建有角色,才出现“分配”铵钮.反之,隐藏. IEnumerable有一个方法,叫Any:
- c#使用Split分割换行符 \r\n
c# 使用Split分割 换行符,方法如下(其余方法有空再添加): string str = "aa" + "\r\n" + "bb"; ...
- Jsp语法简介
1.JSP指令 jsp指令用来设置整个JSP网页想关闭的属性,如网页的编码和脚本语言等.常用的3种指令为page,include和taglib. 2.JSP声明 jsp声明用于声明JSP代表的Serv ...
- PHP跨域form提交
因为安全性因素,直接跨域访问是不被允许的. 1.PHP CURL方式 function curlPost($url,$params) { $postData = ''; foreach($params ...
- windows 7下React Native环境配置
React Native 是 Facebook 推出的一个用 Java 语言就能同时编写 ios,android,以及后台的一项技术,它可以做到实时热更新 .FaceBook 也号称这们技术是 “Le ...