题目:
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
示例:
-
输入:s = 7, nums = [2,3,1,2,4,3]
-
输出:2
-
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
提示:
-
1 <= target <= 10^9
-
1 <= nums.length <= 10^5
-
1 <= nums[i] <= 10^5
方法1:暴力法
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
//要注意nums数组为空的情况
//还要注意s可能为负数
//如果一开始就定义了一个int len=0; 那么len最终一定会为0,所以len的初始化也有讲究
int len=INT32_MAX;//将它赋值为无穷大
int size=nums.size();
for(int i=0;i<size;i++){
int sum=0;
for(int j=i;j<size;j++){
sum=sum+nums[j];
if(sum>=s){
//取最短字串
len=len<(j-i+1)?len:(j-i+1);
break;
}
}
}
//如果字符串为空或者出现这样的情况 s=7 nums=[1,2] 数组所有元素相加都小于s,则没有最小字串
if(len==INT32_MAX){
len=0;
}
return len;
}
};
方法2:移动窗口
#include<iostream>
#include<vector>
using namespace std;
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int size = nums.size();
//慢指针
int p1 = 0;
//快指针
int p2 = 0;
//p1到p2之间元素的总合
int sum = 0;
//p1到p2之间元素的元素个数
int arrnum = INT32_MAX;
//快指针移动
for (; p2 < size; p2++) {
sum += nums[p2];
if (sum >= s) {
//取最小值
arrnum = arrnum < (p2 - p1 + 1) ? arrnum : (p2 - p1 + 1);
if (arrnum == 1) {
return 1;
}
//调整p1的位置 例如[2,8] s=7
while (true) {
sum -= nums[p1];
p1++;
if (sum >= s) {
arrnum--;
//当一个元素大于s,直接返回1
if (arrnum == 1) {
return 1;
}
}
else {
break;
}
}
}
}
if (arrnum == INT32_MAX) {
arrnum = 0;
}
return arrnum;
}
};
int main() {
Solution solu;
vector<int> v;
int s = 9;
v = { 2,3,1,2,4,3 ,5,4};
int result=solu.minSubArrayLen(s, v);
cout << result << endl;
}