[LeetCode] Minimum Size Subarray Sum
2015-06-25 17:33
369 查看
The problem statement has stated that there are both
Well, you may wonder how can it be
There is another
Now let's move on to the
Let's do an example. Suppose we reach
We add a
The code is as follows.
O(n)and
O(nlogn)solutions to this problem. Let's see the
O(n)solution first (taken from this link), which is pretty clever and short.
class Solution { public: int minSubArrayLen(int s, vector<int>& nums) { int start = 0, sum = 0, minlen = INT_MAX; for (int i = 0; i < (int)nums.size(); i++) { sum += nums[i]; while (sum >= s) { minlen = min(minlen, i - start + 1); sum -= nums[start++]; } } return minlen == INT_MAX ? 0 : minlen; } };
Well, you may wonder how can it be
O(n)since it contains an inner
whileloop. Well, the key is that the
whileloop executes at most once for each starting position
start. Then
startis increased by
1and the
whileloop moves to the next element. Thus the inner
whileloop runs at most
O(n)times during the whole
forloop from
0to
nums.size() - 1. Thus both the
forloop and
whileloop has
O(n)time complexity in total and the overall running time is
O(n).
There is another
O(n)solution in this link, which is easier to understand and prove it is
O(n). I have rewritten it below.
class Solution { public: int minSubArrayLen(int s, vector<int>& nums) { int n = nums.size(); int left = 0, right = 0, sum = 0, minlen = INT_MAX; while (right < n) { do sum += nums[right++]; while (right < n && sum < s); while (left < right && sum - nums[left] >= s) sum -= nums[left++]; if (sum >= s) minlen = min(minlen, right - left); } return minlen == INT_MAX ? 0 : minlen; } };
Now let's move on to the
O(nlogn)solution. Well, this less efficient solution is far more difficult to come up with. The idea is to first maintain an array of accumulated summations of elements in
nums. Specifically, for
nums = [2, 3, 1, 2, 4, 3]in the problem statement,
sums = [0, 2, 5, 6, 8, 12, 15]. Then for each element in
sums, if it is not less than
s, we search for the first element that is greater than
sums[i] - s(in fact, this is just what the
upper_boundfunction does) in
sumsusing binary search.
Let's do an example. Suppose we reach
12in
sums, which is greater than
s = 7. We then search for the first element in
sumsthat is greater than
sums[i] - s = 12 - 7 = 5and we find
6. Then we know that the elements in
numsthat correspond to
6, 8, 12sum to a number
12 - 5 = 7which is not less than
s = 7. Let's check for that:
6in
sumscorresponds to
1in
nums,
8in
sumscorresponds to
2in
nums,
12in
sumscorresponds to
4in
nums.
1, 2, 4sum to
7, which is
12in
sumsminus
5in
sums.
We add a
0in the first position of
sumsto account for cases like
nums = [3], s = 3.
The code is as follows.
class Solution { public: int minSubArrayLen(int s, vector<int>& nums) { vector<int> sums = accumulate(nums); int minlen = INT_MAX; for (int i = 1; i <= nums.size(); i++) { if (sums[i] >= s) { int p = upper_bound(sums, 0, i, sums[i] - s); if (p != -1) minlen = min(minlen, i - p + 1); } } return minlen == INT_MAX ? 0 : minlen; } private: vector<int> accumulate(vector<int>& nums) { vector<int> sums(nums.size() + 1, 0); for (int i = 1; i <= nums.size(); i++) sums[i] = nums[i - 1] + sums[i - 1]; return sums; } int upper_bound(vector<int>& sums, int left, int right, int target) { int l = left, r = right; while (l < r) { int m = l + ((r - l) >> 1); if (sums[m] <= target) l = m + 1; else r = m; } if (sums[r] > target) return r; if (sums[l] > target) return l; return -1; } };
相关文章推荐
- Tomcat:bio nio 的设计
- android如何实现两层可滚动view,内层优先响应
- initWithFrame 和 initWithCoder
- Python之dir()与__dict__的区别
- JSTL 的forEach标签循环迭代集合并逆序输出
- Django+MySQL安装配置详解(Linux)[更新为1.8.2版]
- Netty权威指南之文件传输
- HDU 1330 Nearest Common Ancestors(求两个点的最近公共祖先)
- maven工程 缺少插件导致编译不成功问题
- 自动生成Sqlalchemy的models文件
- 面试题47:不用加减乘除做加法
- hybris全渠道电子商务开发视频
- Oracle中的排序
- Java finally语句到底是在return之前还是之后执行?
- C语言数组学习
- json串格式化显示
- JQuery的bind方法效果叠加
- {"未能从程序集“Oracle.ManagedDataAccess, OracleInternal.Common.ConfigBaseClass”。":"OracleInternal.Common.C
- 循环Map的错误做法
- c#sdk的pfop使用代码说明