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. C站投稿189网盘视频源(UP主篇)

    C站投稿189网盘视频源(UP主篇) 现在C站(吐槽弹幕网)的视频来源基本靠的都是189网盘,比如番剧区的每个视频基本来源于此,不像AB两站,拥有自己的资源服务器,为啥呢?没钱啊.都是外来的视频.本站 ...

  2. 利用C#开发移动跨平台Hybrid App(一):从Native端聊Hybrid的实现

    0x00 前言 前一段时间分别读了两篇博客,分别是叶小钗兄的<浅谈Hybrid技术的设计与实现>以及徐磊哥的<从技术经理的角度算一算,如何可以多快好省的做个app>.受到了很多 ...

  3. JQuery Sizzle引擎源代码分析

    最近在拜读艾伦在慕课网上写的JQuery课程,感觉在国内对JQuery代码分析透彻的人没几个能比得过艾伦.有没有吹牛?是不是我说大话了? 什么是Sizzle引擎? 我们经常使用JQuery的选择器查询 ...

  4. Docker 基础 : 数据管理

    用户在使用 Docker 的过程中,往往需要能查看容器内应用产生的数据,或者需要把容器内的数据进行备份,甚至多个容器之间进行数据的共享,这必然涉及容器的数据管理操作.容器中管理数据主要有两种方式:数据 ...

  5. electron之Windows下使用 html js css 开发桌面应用程序

    1.atom/electron github: https://github.com/atom/electron 中文文档: https://github.com/atom/electron/tree ...

  6. NopCommerce 在Category 显示Vendor List列表

    实现效果如下: 1.在前台Web的Category Menu显示 Vendor; 2.点击Vendor 显示Vendor List列表: 主要配置步骤: 1.运行网站 Admin 后台   Categ ...

  7. 【转载】保哥 釐清 CLR、.NET、C#、Visual Studio、ASP.NET 各版本之間的關係

    我常常不仅仅逛 博客园,还会去找国外,特别是台湾的技术部落格,发现好的文章,我便会收录,今天我转载或者全文复制,在Google 博客园,一位叫保哥, 釐清 CLR..NET.C#.Visual Stu ...

  8. 《c# 从入门经典》 (第6版) - 变量和表达式

    1,程序就是对一系列数据的操作:数据最终是存储在内存中的0和1数据流:我们在桌面上的任何操作都会改变内存中的数据. 2,变量存储在计算机中占用着一定的内存空间 bit: 位,计算机的最小存储单位,存储 ...

  9. JDBC_part1_Oracle数据库连接JDBC以及查询语句

    本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! JDBC part1 JDBC概述 jdbc是一种用于 ...

  10. 使用命令 gradle uploadArchives 的异常: Unable to initialize POM pom-default.xml: Failed to validate POM for project

    在使用:gradle uploadArchives 命令对项目进行上传maven时,常常遇到如下报错: 这时候要仔细的检查一下build.gradle文件中的dependencies内容,很多时候是由 ...