209-长度最小的子数组
大约 2 分钟
题目地址(209. 长度最小的子数组 - 力扣(LeetCode))
https://leetcode.cn/problems/minimum-size-subarray-sum/
题目描述
给定一个含有 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 <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 105
进阶:
- 如果你已经实现
O(n)
时间复杂度的解法, 请尝试设计一个O(n log(n))
时间复杂度的解法。
前置知识
- 滑动窗口
- [前缀和+二分查找]
思路1:滑动窗口
定义两个指针 和 分别指向滑动窗口的开始位置和结束位置
计算滑动窗口的总和
当 符合题目时,窗口的长度为子数组的最小长度
- 将 继续往右移,找到更小的窗口长度
- 继续更新子数组的最小长度
关键点
- 当窗口符合条件时,要将 继续往右移,找到更小的窗口长度
代码
- 语言支持:Java
Java Code:
class Solution {
public int minSubArrayLen(int target, int[] nums) {
// 第一次符合条件为窗口长度 right - left
//
int n = nums.length;
if(n == 0) return 0;
int ans = Integer.MAX_VALUE;
int start = 0, end = 0; // 滑动串口的指针和右指针
int sum = 0;
while (end < n) {
sum += nums[end]; // 把当前元素添加进去,直到符合最小窗口的长度
while (sum >= target) { // 最小窗口长度右移,直到不满足 此时,ans = end - start + 1, end - start
ans = Math.min(ans, end - start + 1);
sum -= nums[start];
start++;
}
end++;
}
return ans == Integer.MAX_VALUE ? 0 : ans;
}
}
复杂度分析
令 n 为数组长度。
- 时间复杂度:
- 空间复杂度: