难度:中等
给定一个含有 n
个正整数的数组和一个正整数 target
。
找出该数组中满足其和 ≥ target
的长度最小的 连续子数组 [numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度。如果不存在符合条件的子数组,返回 0
。
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
输入:target = 4, nums = [1,4,4]
输出:1
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0
提示:
进阶:
如果你已经实现 O(n)
时间复杂度的解法, 请尝试设计一个 O(nlog(n))
时间复杂度的解法。
定义两个指针 i
和 j
分别表示子数组(滑动窗口窗口)的开始位置和结束位置,维护变量 sum
存储子数组中的元素和(即从 nums[i]
到 nums[j]
的元素和)。
初始状态下, i
和 j
都指向下标 0
,sum
的值为 0
:
nums[j]
加到 sum
,如果 sum ≥ target
,则更新子数组的最小长度(此时子数组的长度是 j − i + 1
;nums[i]
从 sum
中减去并将 i
右移,直到 sum < target
,在此过程中同样更新子数组的最小长度。j
右移。Java
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int i = 0; // 滑动窗口起始位置
int sum = 0; // 滑动窗口数值之和
int ans = Integer.MAX_VALUE;
for(int j = 0; j < nums.length; j++){
sum += nums[j];//窗口内所有数的和
while(sum >= target) {//窗口内所有数的和大于target,则前移i(起始位置)
ans = ans < j - i + 1 ? ans : j - i + 1;
sum -= nums[i++];// 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
}
}
return ans == Integer.MAX_VALUE ? 0 : ans;
}
}
C++
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int i = 0; // 滑动窗口起始位置
int sum = 0; // 滑动窗口数值之和
int ans = INT_MAX;
for(int j = 0; j < nums.size(); j++){
sum += nums[j];//窗口内所有数的和
while(sum >= target) {//窗口内所有数的和大于target,则前移i(起始位置)
ans = ans < j - i + 1 ? ans : j - i + 1;
sum -= nums[i++];// 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
}
}
return ans == INT_MAX ? 0 : ans;
}
};
n
为数组的长度。题目来源:力扣。
放弃一件事很容易,每天能坚持一件事一定很酷,一起每日一题吧!
关注我LeetCode主页 / CSDN—力扣专栏,每日更新!