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. 滑动窗口
滑动窗口是一种非常常用的技巧,尤其适用于数组或字符串问题,尤其是在求解“最小子数组”和、“最大子数组”等问题时。滑动窗口的基本思想是利用两个指针(通常是left
和right
)来维护一个窗口,然后根据问题的需求动态调整窗口的大小。它的优势在于不需要重新计算窗口内的每个元素,可以实现比暴力算法更高效的时间复杂度。
对于本题“最小长度子数组和大于等于目标值”的问题,我们考虑使用滑动窗口来优化暴力求解的方法。
滑动窗口的核心思路:
- 窗口的定义:我们用两个指针
left
和right
来定义一个滑动窗口,left
是窗口的左边界,right
是窗口的右边界。 - 窗口内的元素和:随着
right
指针的移动,逐渐增大窗口,直到窗口内的和大于等于target
。此时,我们尝试收缩窗口(通过移动left
指针),看能否保持和大于等于target
,并且尽量缩小窗口的大小。 - 更新最小长度:每当窗口内的和满足条件时,我们记录当前窗口的长度,并更新最小长度。
具体设计过程:
-
初始化:
- 用
left
指针表示窗口的左边界,初始值设为0。 - 用
currentSum
记录当前窗口的元素和,初始值设为0。 - 用
minLength
记录最小子数组的长度,初始化为一个极大值(比如Integer.MAX_VALUE
)。
- 用
-
扩展窗口:
- 用
right
指针从左到右扫描数组,每次扩展窗口时,加入nums[right]
到currentSum
中。
- 用
-
收缩窗口:
- 一旦
currentSum
大于等于target
,我们就尝试通过移动left
指针来缩小窗口,直到currentSum
小于target
为止。在每次缩小窗口时,我们更新最小子数组的长度。
- 一旦
-
返回结果:
- 最终返回记录的最小子数组长度。如果没有找到满足条件的子数组,返回0。
代码实现:
public class Solution {
public int minSubArrayLen(int target, int[] nums) {
int n = nums.length;
int minLength = Integer.MAX_VALUE;
int currentSum = 0;
int left = 0;
for (int right = 0; right < n; right++) {
// 扩展窗口,增加当前元素
currentSum += nums[right];
// 当窗口和大于等于目标值时,尝试收缩窗口
while (currentSum >= target) {
// 更新最小长度
minLength = Math.min(minLength, right - left + 1);
// 收缩窗口,减去左边界的元素
currentSum -= nums[left];
left++;
}
}
return minLength == Integer.MAX_VALUE ? 0 : minLength;
}
}
代码解释:
-
初始化:
minLength
用来记录最小子数组的长度,初始化为Integer.MAX_VALUE
,表示暂时还没有符合条件的子数组。currentSum
记录当前窗口内的和。left
表示窗口的左边界。
-
扩展窗口:
- 我们通过
right
指针从左到右遍历数组,每次right
向右移动时,将nums[right]
加入currentSum
中。
- 我们通过
-
收缩窗口:
- 一旦
currentSum
大于等于target
,就开始尝试通过left++
来缩小窗口,减去左边界的元素,直到currentSum
小于target
。 - 在每次收缩窗口时,更新
minLength
为right - left + 1
(即当前窗口的长度)。
- 一旦
-
结果返回:
- 如果
minLength
仍然是Integer.MAX_VALUE
,说明没有找到符合条件的子数组,返回0。否则返回minLength
。
- 如果
本文作者:Drunker•L
本文链接:https://www.cnblogs.com/drunkerl/p/18658242
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步