209. Minimum Size Subarray Sum
2016-03-23 14:26
281 查看
Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn’t one, return 0 instead.
For example, given the array [2,3,1,2,4,3] and s = 7,
the subarray [4,3] has the minimal length under the problem constraint.
click to show more practice.
More practice:
If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n).
O(n^2)解法:两重循环,以长度len为外重循环,内重循环控制subarray的起始位置。
以下转自:http://www.cnblogs.com/grandyang/p/4501934.html
O(n)解法:
我们需要定义两个指针left和right,分别记录子数组的左右的边界位置,然后我们让right向右移,直到子数组和大于等于给定值或者right达到数组末尾,此时我们更新最短距离,并且将left像右移一位,然后再sum中减去移去的值,然后重复上面的步骤,直到right到达末尾,且left到达临界位置,即要么到达边界,要么再往右移动,和就会小于给定值。
O(nlogn)解法:
这个解法要用到二分查找法,思路是,我们建立一个比原数组长一位的sums数组,其中sums[i]表示nums数组中[0, i - 1]的和,然后我们对于sums中每一个值sums[i],用二分查找法找到子数组的右边界位置,使该子数组之和大于sums[i] + s,然后我们更新最短长度的距离即可。
For example, given the array [2,3,1,2,4,3] and s = 7,
the subarray [4,3] has the minimal length under the problem constraint.
click to show more practice.
More practice:
If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n).
O(n^2)解法:两重循环,以长度len为外重循环,内重循环控制subarray的起始位置。
class Solution { public: int minSubArrayLen(int s, vector<int>& nums) { if(nums.size() == 0){ return 0; } int sum = 0; for(int len = 1; len <= nums.size(); len ++){ sum = 0; for(int ind = 0; ind < len; ind ++){ //count the subarray starts from the 0th num, whose lenth is len; sum += nums[ind]; } if(sum >= s) return len; for(int beg = 1; beg <= nums.size() - len; beg ++){ sum = sum - nums[beg - 1] + nums[beg + len - 1]; if(sum >= s) return len; } } } };
以下转自:http://www.cnblogs.com/grandyang/p/4501934.html
O(n)解法:
我们需要定义两个指针left和right,分别记录子数组的左右的边界位置,然后我们让right向右移,直到子数组和大于等于给定值或者right达到数组末尾,此时我们更新最短距离,并且将left像右移一位,然后再sum中减去移去的值,然后重复上面的步骤,直到right到达末尾,且left到达临界位置,即要么到达边界,要么再往右移动,和就会小于给定值。
// O(n) class Solution { public: int minSubArrayLen(int s, vector<int>& nums) { if (nums.empty()) return 0; int left = 0, right = 0, sum = 0, len = nums.size(), res = len + 1; while (right < len) { while (sum < s && right < len) { sum += nums[right++]; } while (sum >= s) { res = min(res, right - left); sum -= nums[left++]; } } return res == len + 1 ? 0 : res; } };
O(nlogn)解法:
这个解法要用到二分查找法,思路是,我们建立一个比原数组长一位的sums数组,其中sums[i]表示nums数组中[0, i - 1]的和,然后我们对于sums中每一个值sums[i],用二分查找法找到子数组的右边界位置,使该子数组之和大于sums[i] + s,然后我们更新最短长度的距离即可。
class Solution { public: int minSubArrayLen(int s, vector<int>& nums) { int len = nums.size(), sums[len + 1] = {0}, res = len + 1; for (int i = 1; i < len + 1; ++i) sums[i] = sums[i - 1] + nums[i - 1]; for (int i = 0; i < len + 1; ++i) { int right = searchRight(i + 1, len, sums[i] + s, sums); if (right == len + 1) break; if (res > right - i) res = right - i; } return res == len + 1 ? 0 : res; } int searchRight(int left, int right, int key, int sums[]) { while (left <= right) { int mid = (left + right) / 2; if (sums[mid] >= key) right = mid - 1; else left = mid + 1; } return left; } };
相关文章推荐
- 二维码扫描过快奔溃结果处理
- HRBUST 2007 小Q的生日 (日期陷阱)
- redis主从的配置和使用
- Swift/Objective-C-Swift与Objective-C混用教程
- for循环操作集合,及增删改查,和增强for循环的循环迭代
- Ubuntu查看系统信息
- spine动画getBoundingBox获取size不准
- linux下虚拟机找不到虚拟光驱cdrom
- 【UNET自学日志】Part1 UNET的设置与运动同步
- iOS9横竖屏设置的处理方法和实例讲解
- ios 调试技巧
- RatingBar(星级评分条)
- Servlet开发入门
- 人脸关键点检测
- ibatis学习
- 2.4.2程序作业
- mybatis:@Intercepts小例子(一)
- 使用docker搭建nginx
- react-native 之布局篇
- 代码评审小结