Count of Range Sum(leetcode)
2017-10-14 12:08
218 查看
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
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.
题目解析
题目的要求就是求原数组的子数组个数,子数组满足“子数组的数之和在给定的范围[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 327 Count of Range Sum
- [LeetCode]Count of Range Sum
- [leetcode]Count of Range Sum
- LeetCode 327 Count of Range Sum(分治)
- Leetcode327——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_c++:Divide and Conquer:Count of Range Sum(327)
- LeetCode Count of Range Sum
- [leetcode-327]Count of Range Sum(java)
- LeetCode-Count of Range Sum
- 2017-09-14 LeetCode_327 Count of Range Sum
- [LeetCode 327] Count of Range Sum
- 327_Count of Range Sum