leetcode题库的第209题:长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [nums l, nums l+1, ..., nums r-1, nums r] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
首先需要正确理解题意,要求是在数组中找连续子数组,将连续子数组相加,得到的值大于目标值,满足这个条件的所有子数组中长度最小的哪个有多长。
暴力求解思路
将所有子数组的和求出来,排除掉小于目标值的,再从中找到长度最小的。暴力求解的时间复杂度是n*n
改进方法
暴力求解中列出所有满足和大于目标值这一步是可以优化的,由于是连续子数组所以可以让两个指针进行移动,形成滑动效果,当满足条件时记录下该子数组的长度即可,然后继续滑动。
举例
假设数组为[2,3,1,2,4,3],目标值target=7
从图上可知,通过动态移动start指针和end指针,实现统计满足条件的子数组长度,不断比较长度大小关系只保留最小的那个长度。
代码实现
class Solution {
public:
int minSubArrayLen(int target, vector<int>& nums) {
int startNum=0;
int endNum=0;
int result=0;
int temp=nums.size();
for(;endNum<nums.size();endNum++){
result=result+nums[endNum];
while(result>=target){
if(temp>endNum-startNum){
temp=endNum-startNum+1;
}
if ((result-nums[startNum])>=target){ //此处先判断如果移动start是否依旧满足条件
result=result-nums[startNum];
startNum++;
}
else if ((result-nums[startNum])<target){ //这个跳出条件是当避免死循环
break;
}
}
cout<<startNum<<9<<endNum;
}
if (result<target){return 0;}
else{return temp;}
}
};
这种解法的时间复杂度是2*n,在代码书写的细节上还有改进空间。