Count of Range Sum(leetcode)
来源:互联网 发布:网络策划是做什么的 编辑:程序博客网 时间:2024/06/10 13:36
Count of Range Sum
- Count of Range Sum
- 题目
- 题目解析
- 解决办法
- sum数数
- 归并排序
题目
leetcode题目
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(
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
.
题目解析
题目的要求就是求原数组的子数组个数,子数组满足“子数组的数之和在给定的范围[lower, upper]
内”条件。
例子中,nums
= [-2, 5, -1]
,子数组为
[-2]
=>[0, 0]
[5]
=>[1, 1]
[-1]
=>[2, 2]
[-2, 5]
=>[0, 1]
[5, -1]
=>[1, 2]
[-2, 5, -1]
=>[0, 2]
子数组的总和在[-2, 2]
中的子数组为[-2]
、[-1]
、[-2, 5, -1]
,个数为3。
解决办法
1. sum数数
令sums[i] = nums[0] + nums[1] + … + nums[i]
。
找到满足条件lower <= sums[j] - sums[i] <= upper
的区间[i, j](i <= j)
,即我们需要找到满足sums[j] - upper <= sums[i] <= sums[j] - lower
的i
的个数。
PS:函数distance(iterator start, iterator end)
,迭代器start可以通过某种方法到达end,函数distance返回的是start到end的个数。
class Solution {public: int countRangeSum(vector<int>& nums, int lower, int upper) { int res = 0; long long sum = 0; multiset<long long> sums; sums.insert(0); for (int i = 0; i < nums.size(); ++i) { sum += nums[i]; res += distance(sums.lower_bound(sum - upper), sums.upper_bound(sum - lower)); sums.insert(sum); } return res; } };
2. 归并排序
将数组sums
分为两部分:左半部left和右半部right。由于数组sums
在构建的时候已经呈递增顺序,使得left
和right
已经排好序了。当我们遍历left
时候,在right
找到满足以下条件的j, k
:
sums[j] - sums[i] > upper
,j
是满足该不等式的第一个下标sums[k] - sums[i] >= lower
,k
是满足该不等式的第一个下标
那么在[lower, upper]之间的区间的个数是j - k
。
同时我们也需要另一个下标t,用来拷贝所有满足sums[t] < sums[i]到一个寄存器Cache中以完成混合排序的过程。
class Solution {public: int countRangeSum(vector<int>& nums, int lower, int upper) { int s = nums.size(); vector<long> sums(s + 1, 0); for (int i = 0; i < nums.size(); ++i) { sums[i + 1] = sums[i] + nums[i]; } return countAndMergeSort(sums, 0, sums.size(), lower, upper); } int countAndMergeSort(vector<long> &sums, int start, int end, int lower, int upper) { if (end - start <= 1) return 0; int mid = start + (end - start) / 2; int count = countAndMergeSort(sums, start, mid, lower, upper) + countAndMergeSort(sums, mid, end, lower, upper); int j = mid; int k = mid; int t = mid; vector<int> cache(end - start, 0); for (int i = start, r = 0; 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]; count += j - k; } copy(cache.begin(), cache.begin() + t - start, sums.begin() + start); return count; }};
- leetcode Count of Range Sum
- LeetCode Count of Range Sum
- [LeetCode]Count of Range Sum
- Leetcode Count of Range Sum
- leetcode Count of Range Sum
- []LeetCode]Count of Range Sum
- [LeetCode] Count of Range Sum
- Count of Range Sum(leetcode)
- <LeetCode OJ> 327. Count of Range Sum
- leetcode 327. Count of Range Sum
- Leetcode 327. Count of Range Sum[hard]
- LeetCode 327. Count of Range Sum
- leetcode 327.Count of Range Sum
- Leetcode #327 Count of Range Sum
- [leetcode]Count of Range Sum
- LeetCode 327. Count of Range Sum
- LeetCode 327 Count of Range Sum
- LeetCode 327. Count of Range Sum
- shiro学习
- 静态代码检查工具 cppcheck
- UVA 572
- Django数据库补充之事务
- C语言-实参到函数形参传递的理解
- Count of Range Sum(leetcode)
- [monitor] 7. Linux几种内核故障定位方法
- Spring配置Listener监听器
- 程序员笑话全集
- Tesseract-OCR识别中文与训练字库实例
- sql标签和include标签使用.封装SQL语句
- c++string类的简单实现
- 随机生成六位校验码
- Java中实现多线程