给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。
示例:
输入: s = 7, nums = [2,3,1,2,4,3]
输出: 2
解释: 子数组 [4,3] 是该条件下的长度最小的连续子数组。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum
解题思路:
1、暴力解法:双for循环
解答时要注意边界问题,所以内层的for要从相同i开始而不是i+1.
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int re_=nums.size()+1;
for(int i=0;i<nums.size();i++)
{
int temp=0;
for(int j=i;j<nums.size();j++)
{
if( j==i) temp+=0;
else temp+=nums[j];
if(nums[i]+temp>=s)
{
re_=(j-i+1)>re_?re_:(j-i+1);
break;
}
}
}
return re_;
}
};
通过 | 544 ms | 9.8 MB | Cpp |
2、双索引(滑动窗口):
暴力解法中含有大量的重复计算,当使用双索引时,左右索引不断根据和前后移动,避免重复计算。
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int l=0,r=-1;//左右索引
int re_=nums.size()+1;//返回值
int sum_=0;//滑动窗口累加和
while(l<nums.size())
{
if(r+1<nums.size() && sum_<s)
{
r++;
sum_+=nums[r];
}
else
{ if(sum_>=s) re_=re_>(r-l+1)?(r-l+1):re_;
sum_-=nums[l];
l++;
}
}
if (re_==nums.size()+1)//无解
return 0;
return re_;
}
};
通过 | 12 ms | 9.9 MB | Cpp |
时间复杂度O(n),空间复杂度O(1)。
不过要注意临界值,r+1<nums.size(),防止越界,同时若写成减法r<nums.size()-1则要保证nums长度>1,;
同时当nums为空时,或该题目无解时,return 0;