【LeetCode】327. Count of Range Sum
2016-04-13 20:03
363 查看
题目:
Given an integer arraynums, 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
numsbetween indices
iand
j(
i≤
j), inclusive.
Note:
A naive algorithm of O(n2) is trivial. You MUST do better than that.
Example:
Given nums =
[-2, 5, -1], lower =
-2, upper =
2, Return
3. The three ranges are :
[0, 0],
[2, 2],
[0, 2]and their respective sums are:
-2, -1, 2.
提示:
这道题最直观的一个想法就是枚举出所有的子数组,然后检查他们是否在要求的取值范围内,这种方法的时间复杂度是O(n^2)的,显然会超时。看到这种题目最容易想到的是什么呢?Two Pointers!对,但是在这道题上仅仅使用Two Pointers肯定是不够的,在Two Pointers的思想基础上,融合归并排序,就能找到一个比较好的解决方案。
这里我们的排序对象是前缀求和数组,在归并排序的合并阶段,我们有左数组和右数组,且左和右数组都是排好序的,所以我们可以用i遍历左数组,j,k两个指针分别取在右数组搜索,使得:
sums[j] - sums[i] < upper
sums[k] - sums[i] >= lower
那么此时,我们就找到了j-k个符合要求的子数组。
由于左右数组都是排好序的,所以当i递增之后,j和k的位置不用从头开始扫描。
最后还有一点需要注意的就是,为了防止溢出,我们的vector容纳的是long long型元素。
代码:
class Solution { public: int countRangeSum(vector<int>& nums, int lower, int upper) { int n = nums.size(); if (n <= 0) { return 0; } vector<long long> sums(n + 1, 0); for (int i = 0; i < n; ++i) { sums[i+1] = sums[i] + nums[i]; } return merge(sums, 0, n, lower, upper); } int merge(vector<long long>& sums, int start, int end, int lower, int upper) { if (start >= end) { return 0; } int mid = start + (end - start) / 2; int count = merge(sums, start, mid, lower, upper) + merge(sums, mid + 1, end, lower, upper); vector<long long> tmp(end - start + 1, 0); int j = mid + 1, k = mid + 1, t = mid + 1, i = start, r = 0; for (; i <= mid; ++i, ++r) { while (j <= end && sums[j] - sums[i] <= upper) ++j; while (k <= end && sums[k] - sums[i] < lower) ++k; count += j - k; while (t <= end && sums[t] <= sums[i]) tmp[r++] = sums[t++]; tmp[r] = sums[i]; } for (int i = 0; i < r; ++i) { sums[start + i] = tmp[i]; } return count; } };
相关文章推荐
- 解决ListView下拉刷新时导致图片闪烁问题
- lm3488升压芯片电路调试 boost
- eclipse设置的断点上有斜线
- 最长滑雪路径
- 华为2016年精英挑战赛总结
- 第七周周记
- bitmap格式分析
- hdu1908
- JSP的CSS背景样式写法
- 程序猿二三事之工具使用-Eclipse常用快捷键
- Android UI-实现底部切换标签(fragment)
- visual studio 2013和sql server数据库连接
- 关于开发新一代大数据分布式关系数据库的倡议
- 栈的应用 逆波兰式
- C++游戏系列5:不止有一件武器
- hibernate分页查询和方言
- Leetcode no.33
- 菜鸟学python(10) 用python处理Layer导出的域名(将每个域名前加入http://)
- SQL优化的部分内容
- jquery请求servlet实现ajax异步请求