209. 长度最小的子数组

题目描述:

给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。

示例:

输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。

进阶:

如果你已经完成了O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。

思路:

1. 用双指针 left 和 right 表示一个窗口。sum来表示窗口内数字的和。
2. right 向右移增大窗口,sum随之增加,直到窗口内的数字和sum大于等于了 s。进行第 3 步。
3. 记录此时的长度,left 向右移动,开始减少长度,sum减去移除窗口的数字,每减少一次,就更新最小长度。直到当前窗口内的数字和小于了 s,回到第 2步。

Java双指针解法:

class Solution {
    public int minSubArrayLen(int s, int[] nums) {
        int len = nums.length;
        if (len == 0) {
            return 0;
        }
        int left = 0;
        int right = 0;
        int sum = 0;
        int min = Integer.MAX_VALUE;
        while (right < len) {
            sum += nums[right];
            right++;
            while (sum >= s) {
                min = Math.min(min, right - left);
                sum -= nums[left];
                left++;
            }
        }
        return min == Integer.MAX_VALUE ? 0 : min;
    }
}

python3解法:

class Solution:
    def minSubArrayLen(self, s: int, nums: List[int]) -> int:
        length = len(nums)
        if length == 0:
            return 0
        left = 0
        right = 0
        sums = 0
        minlen = sys.maxsize
        while right < length:
            sums += nums[right]
            right += 1
            while sums >= s:
                minlen = min(minlen, right - left)
                sums -= nums[left]
                left += 1
        if minlen == sys.maxsize :
            return 0
        else:
            return minlen

暴力解法:
思路:

从第 0 个数字开始,依次添加数字,记录当总和大于等于 s 时的长度。

从第 1 个数字开始,依次添加数字,记录当总和大于等于 s 时的长度。

从第 2 个数字开始,依次添加数字,记录当总和大于等于 s 时的长度。

...

从最后个数字开始,依次添加数字,记录当总和大于等于 s 时的长度。

从上边得到的长度中选择最小的即可。

java代码实现

class Solution {
    public int minSubArrayLen(int s, int[] nums) {
        //暴力解法
        int len = nums.length;
        if (len == 0) {
            return 0;
        }
        int min = Integer.MAX_VALUE;
        for(int i = 0; i < len; i++){
            int right = i;
            int sum = 0;
            while(right < len)
            {
                sum += nums[right];
                right++;
                if(sum >= s)
                {
                    min = Math.min(min, right - i);
                    break;
                }
            }

        }
        return min == Integer.MAX_VALUE ? 0 : min;
    }
}

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum

你可能感兴趣的:(209. 长度最小的子数组)