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] 209. Minimum Size Subarray Sum 最短子数组之和的更多相关文章

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

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

  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 209. Minimum Size Subarray Sum (最短子数组之和)

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

  4. LeetCode 209 Minimum Size Subarray Sum

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

  5. Java for LeetCode 209 Minimum Size Subarray Sum

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

  6. 【刷题-LeetCode】209. Minimum Size Subarray Sum

    Minimum Size Subarray Sum Given an array of n positive integers and a positive integer s, find the m ...

  7. LeetCode OJ 209. Minimum Size Subarray Sum

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

  8. [LeetCode] 930. Binary Subarrays With Sum 二元子数组之和

    In an array A of 0s and 1s, how many non-empty subarrays have sum S? Example 1: Input: A = [1,0,1,0, ...

  9. 【LeetCode】209. Minimum Size Subarray Sum 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/minimum- ...

随机推荐

  1. ThinkPHP 3.2 自定义基类 Model

    ThinkPHP 提供了一个 Model 类,供其他的 Model 进行继承.Model 类中是 MVC 中的模型类,它是调用 持久层 的上层类.感觉这么描述问题很多,但是有什么办法呢?但是,这个 M ...

  2. Uboot启动流程分析(二)

    1.前言 在前面的文章Uboot启动流程分析(一)中,链接如下: https://www.cnblogs.com/Cqlismy/p/12000889.html 已经简单地分析了low_level_i ...

  3. Vue 结合 SignalR 实现前后端实时消息同步

    最近业务中需要实现服务器端与客户端的实时通信功能,对Signalr做了一点总结和整理. SignalR 作为  ASP.NET 的一个库,能够简单方便地为应用提供实时的服务器端与客户端双向通信功能. ...

  4. Installing on Kubernetes with NATS Operator

    https://github.com/nats-io/nats-operator https://hub.helm.sh/charts/bitnami/nats https://github.com/ ...

  5. Logstash:处理多个input

    Logstash:处理多个input Logstash的整个pipleline分为三个部分: input插件:提取数据. 这可以来自日志文件,TCP或UDP侦听器,若干协议特定插件(如syslog或I ...

  6. kali渗透综合靶机(四)--node1靶机

    kali渗透综合靶机(四)--node1靶机 靶机下载地址::https://download.vulnhub.com/node/Node.ova 一.主机发现 1.netdiscover -i et ...

  7. Linux PHP安装xdebug扩展及PHPstorm调试

    前言:使用IDE编辑器的时候如PHPstorm,为了方便调试,这里安装PHP的扩展xdebug.安装环境为Linux centos7.3 一.下载xdebug扩展 官网:https://xdebug. ...

  8. ASP.NET Core中的jQuery Unobtrusive Ajax帮助器

    最近在ASP.NET Core下写文章管理系统时,准备在分页显示文章内容时,使用Ajax.网上找了篇帖文,简单翻一下,仅供自己查阅. 原链接:https://dotnetthoughts.net/jq ...

  9. c# 值类型和引用类型 笔记

    参考以下博文,我这里只是笔记一下,原文会更加详细 c#基础系列1---深入理解值类型和引用类型 堆栈和托管堆c# 值类型和引用类型 红色表示——“这啥?”(真实1个问题引出3个问题) CLR支持的两种 ...

  10. python3之int类的常用方法练习

    int类的常用方法练习 #coding:utf-8 #int类的常用方法 num1 = 18 num2 = -15 #查询创建num1所用的类 print(type(num1)) #num1占用的最小 ...