Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead.

Example:

Input: s = 7, nums = [2,3,1,2,4,3]
Output: 2
Explanation: the subarray [4,3] has the minimal length under the problem constraint.
Follow up:
If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n).  

Credits:
Special thanks to @Freezen for adding this problem and creating all test cases.

这道题给定了我们一个数字,让求子数组之和大于等于给定值的最小长度,注意这里是大于等于,不是等于。跟之前那道 Maximum Subarray 有些类似,并且题目中要求实现 O(n) 和 O(nlgn) 两种解法,那么先来看 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 ;
int left = , right = , sum = , len = nums.size(), res = len + ;
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 + ? : res;
}
};

同样的思路,我们也可以换一种写法,参考代码如下:

解法二:

class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int res = INT_MAX, left = , sum = ;
for (int i = ; i < nums.size(); ++i) {
sum += nums[i];
while (left <= i && sum >= s) {
res = min(res, i - left + );
sum -= nums[left++];
}
}
return res == INT_MAX ? : res;
}
};

下面再来看看 O(nlgn) 的解法,这个解法要用到二分查找法,思路是,建立一个比原数组长一位的 sums 数组,其中 sums[i] 表示 nums 数组中 [0, i - 1] 的和,然后对于 sums 中每一个值 sums[i],用二分查找法找到子数组的右边界位置,使该子数组之和大于 sums[i] + s,然后更新最短长度的距离即可。代码如下:

解法三:

// O(nlgn)
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int len = nums.size(), sums[len + ] = {}, res = len + ;
for (int i = ; i < len + ; ++i) sums[i] = sums[i - ] + nums[i - ];
for (int i = ; i < len + ; ++i) {
int right = searchRight(i + , len, sums[i] + s, sums);
if (right == len + ) break;
if (res > right - i) res = right - i;
}
return res == len + ? : res;
}
int searchRight(int left, int right, int key, int sums[]) {
while (left <= right) {
int mid = (left + right) / ;
if (sums[mid] >= key) right = mid - ;
else left = mid + ;
}
return left;
}
};

我们也可以不用为二分查找法专门写一个函数,直接嵌套在 for 循环中即可,参加代码如下:

解法四:

class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int res = INT_MAX, n = nums.size();
vector<int> sums(n + , );
for (int i = ; i < n + ; ++i) sums[i] = sums[i - ] + nums[i - ];
for (int i = ; i < n; ++i) {
int left = i + , right = n, t = sums[i] + s;
while (left <= right) {
int mid = left + (right - left) / ;
if (sums[mid] < t) left = mid + ;
else right = mid - ;
}
if (left == n + ) break;
res = min(res, left - i);
}
return res == INT_MAX ? : res;
}
};

讨论:本题有一个很好的 Follow up,就是去掉所有数字是正数的限制条件,而去掉这个条件会使得累加数组不一定会是递增的了,那么就不能使用二分法,同时双指针的方法也会失效,只能另辟蹊径了。其实博主觉得同时应该去掉大于s的条件,只保留 sum=s 这个要求,因为这样就可以在建立累加数组后用 2sum 的思路,快速查找 s-sum 是否存在,如果有了大于的条件,还得继续遍历所有大于 s-sum 的值,效率提高不了多少。

Github 同步地址:

https://github.com/grandyang/leetcode/issues/209

类似题目:

Minimum Window Substring

Subarray Sum Equals K

Maximum Length of Repeated Subarray

参考资料:

https://leetcode.com/problems/minimum-size-subarray-sum/

https://leetcode.com/problems/minimum-size-subarray-sum/discuss/59090/C%2B%2B-O(n)-and-O(nlogn)

https://leetcode.com/problems/minimum-size-subarray-sum/discuss/59078/Accepted-clean-Java-O(n)-solution-(two-pointers)

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Minimum Size Subarray Sum 最短子数组之和的更多相关文章

  1. [LeetCode] 209. Minimum Size Subarray Sum 最短子数组之和

    Given an array of n positive integers and a positive integer s, find the minimal length of a contigu ...

  2. Minimum Size Subarray Sum 最短子数组之和

    题意 Given an array of n positive integers and a positive integer s, find the minimal length of a suba ...

  3. [LeetCode] Minimum Size Subarray Sum 解题思路

    Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...

  4. [leetcode]523. Continuous Subarray Sum连续子数组和(为K的倍数)

    Given a list of non-negative numbers and a target integer k, write a function to check if the array ...

  5. (leetcode)Minimum Size Subarray Sum

    Given an array of n positive integers and a positive integer s, find the minimal length of a subarra ...

  6. [LintCode] Continuous Subarray Sum 连续子数组之和

    Given an integer array, find a continuous subarray where the sum of numbers is the biggest. Your cod ...

  7. lintcode :continuous subarray sum 连续子数组之和

    题目 连续子数组求和 给定一个整数数组,请找出一个连续子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的值.(如果两个相同的答案,请返回其中任意一个) 样例 给定 [-3, ...

  8. LeetCode Minimum Size Subarray Sum (最短子序列和)

    题意:给一个序列,找出其中一个连续子序列,其和大于s但是所含元素最少.返回其长度.0代表整个序列之和均小于s. 思路:O(n)的方法容易想.就是扫一遍,当子序列和大于s时就一直删减子序列前面的一个元素 ...

  9. LeetCode—Minimum Size Subarray Sum

    题目: Given an array of n positive integers and a positive integer s, find the minimal length of a sub ...

随机推荐

  1. 【十大经典数据挖掘算法】EM

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 1. 极大似然 极大似然(Maxim ...

  2. Angular2 小贴士 NgModule 模块

    angular2 具有了模块的概念,响应了后台程序的号召,高内聚 低耦合.模块就是用来进行封装,进行高内聚  低耦合的功能. 其实各人认为ng2 的模块和.net的工程类似,如果要使用模块中定义的功能 ...

  3. 文字处理控件TX Text Control的使用

    这几天一直在研究TX Text Control的使用,由于这方面的资料相对比较少,主要靠下载版本的案例代码进行研究,以及官方的一些博客案例进行学习,使用总结了一些心得,特将其总结出来,供大家分享学习. ...

  4. 【C#公共帮助类】 WebHelper帮助类

    如果你是一个新手,如果你刚接触MVC,如果你跟着置顶的那个项目,我们肯定会用到这里面的几个帮助类 它们都在Common类库下,大家一定要记住要点:取其精华去其糟粕,切勿拿来主义~ Applicatio ...

  5. Java之继承、抽象类、接口篇

    一.继承(extends) 什么是继承? 继承是对现实生活中的"分类"概念的一种模拟. 狮子拥有动物的一切基本特性,但同时又拥有自己的独特的特性,这就是"继承" ...

  6. Jquery元素选取、常用方法

    一:常用的选择器:(李昌辉) 基本选择器 $("#myDiv") //匹配唯一的具有此id值的元素 $("div") //匹配指定名称的所有元素 $(" ...

  7. 让IIS7.0.0.0支持 .iso .7z .torrent .apk等文件下载的设置方法

    IIS默认支持哪些MIME类型呢,我们可以这样查看:打开IIS管理器(计算机--管理--服务和应用程序--Internet信息服务(IIS)管理器:或者Win+R,输入inetmgr,Enter),在 ...

  8. [deviceone开发]-心形点赞动画示例

    一.简介 这个示例展示do_Animator组件的简单使用,通过点击"点赞"按钮,不断弹出心形图片,向上动画漂移到顶部消失.间隔时间和上下左右移动的步长都是一定范围的随机值.二.效 ...

  9. EasyUI+Knockout实现经典表单的查看、编辑

    此文章是基于 1. 搭建SpringMVC+Spring+Hibernate平台 2. 自制xml实现SQL动态参数配置 3. 利用DetachedCriteria构建HQL参数动态匹配 4. 常用日 ...

  10. JDBC数据库访问操作的动态监测 之 Log4JDBC

    log4jdbc是一个JDBC驱动器,能够记录SQL日志和SQL执行时间等信息.log4jdbc使用SLF4J(Simple Logging Facade)作为日志系统. 特性: 1.支持JDBC3和 ...