LeetCode 209. 长度最小的子数组——medium
前言
本文旨在记录与分享个人的刷题经验,因水平受限,观点难免偏颇,欢迎大家在评论区交流意见!
LeetCode 209. 长度最小的子数组
LeetCode 209. 长度最小的子数组
给定一个含有 n
个正整数的数组和一个正整数 target
。
找出该数组中满足其和 ≥ target
的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4]
输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
提示:
1 <= target <= 10^9
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^5
进阶:
如果你已经实现 O(n)
时间复杂度的解法, 请尝试设计一个 O(n log(n))
时间复杂度的解法。
解法一:滑动窗口—— O ( n ) O(n) O(n)
思路——滑动窗口确定区间
分析:
- 通过快慢指针快速找到指定区间
- 再通过移动慢指针缩区间
步骤——快慢指针 → \rightarrow →缩减区间 → \rightarrow →记录
步骤:
- ①快慢指针——慢指针固定在左端,快指针向右移动找到指定区间
- ②缩减区间——如果
[slow,quick]
序列符合题意,则令slow++
直到不符合位置,进入下次循环 - ③记录最短子数组——用一个
len
来记录,每次变更时取Math.min(len,quick - slow + 1)
实现代码
class Solution {
public int minSubArrayLen(int target, int[] nums) {
//定义len大于nums.length即可,以便判断是否有这个区间(如果设置为nums.length,则不便于判断)
int len = nums.length + 1;
int quick = 0;
int slow = 0;
int sum = 0;
//循环条件:快指针在数组范围内
while(quick < nums.length){
sum += nums[quick];
//当区间内的和满足题意时,进行缩减区间,否则继续挪动快指针
while(sum >= target){
len = Math.min(len,quick - slow + 1);
sum -= nums[slow];
slow ++;
}
quick ++;
}
//如果len没发生变化,意味着没找到符合条件的区间,返回0;否则返回len
if(len == nums.length + 1){
return 0;
}else{
return len;
}
}
}
复杂度分析
时间复杂度: O ( n ) O(n) O(n)——快慢指针最多各移动 n n n次
空间复杂度: O ( 1 ) O(1) O(1)