题目链接
https://leetcode-cn.com/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
提示
暴力法思路
假设子数组左边left,右边right,起始位置都为0.?
固定left,right一直向右移动,直到子数组内所有元素的和大于等于target,即找到了对于当前位置的left的最小子串长度(子数组长度),或者right已经走到尾部也停止。
left依次右移并最新的子串最小值。
C++ Code
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int left=0,right=0,min_len=INT_MAX;
int sum=0;
for(left;left<nums.size();left++)
{
if(left==0) sum+=nums[left];
else sum-=nums[left-1];
while(right<nums.size()-1&&sum<target)
{
right++;
sum+=nums[right];
}
if(sum>=target)
{
min_len=right-left+1;
}
}
return min_len==INT_MAX?0:min_len;
}
};
滑动窗口法思路
定义两个指针start 和 end 分别表示子数组(滑动窗口窗口)的开始位置和结束位置,维护变量 sum 存储子数组中的元素和(即从 nums[start] 到 nums[end] 的元素和)。
初始状态下,start 和end 都指向下标 0,sum 的值为 00。
每一轮迭代,将 nums[end] 加到 sum,如果sum≥s,则更新子数组的最小长度(此时子数组的长度是 end?start+1),然后将nums[start] 从 sum 中减去并将 start 右移,直到sum<s,在此过程中同样更新子数组的最小长度。在每一轮迭代的最后,将end 右移。
C++ Code
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int n = nums.size();
if (n == 0) {
return 0;
}
int ans = INT_MAX;
int start = 0, end = 0;
int sum = 0;
while (end < n) {
sum += nums[end];
while (sum >= s) {
ans = min(ans, end - start + 1);
sum -= nums[start];
start++;
}
end++;
}
return ans == INT_MAX ? 0 : ans;
}
};
|