力扣刷题 209 长度最小的子数组--day2
题目分析
??? 在写代码前, 还是要好好分析, 最好在纸上把题目的过程模拟以下
思路清晰,代码才会不写的很乱,
像这道题,一开始很难想到用滑动窗口的, 只有在纸上模拟了子数组的变化过程才写的出来!
今天时间有点紧, 题解就不分析过多了,
我的解法
//自己的写法, 本质上是滑动窗口
int minSubArrayLen(int target, vector<int>& nums) {
int size = nums.size();
int left = 0, right = 0;
int ll = 0,rr = 0;
int sum = 0, minLength = 100005;
while(right < size){
while(right < size && sum < target){
sum += nums[right];
right++;
}
if(sum < target){
break;
}
while(sum >= target){
sum -= nums[left];
left++;
}
if(right - left + 1 < minLength){
minLength = right - left + 1;
ll = left - 1;
rr = right - 1;
}
}
if(minLength == 100005) return 0;
else {
for(int i = ll; i <= rr; i++){
cout<< nums[i]<<" ";
}
return minLength;
}
}
carl 哥的精炼版本
省去了不必要的循环
// 代码精炼版
int minSubArrayLen(int s, vector<int>& nums) {
int result = INT32_MAX;
int sum = 0; // 滑动窗口数值之和
int i = 0; // 滑动窗口起始位置
int subLength = 0; // 滑动窗口的长度
for (int j = 0; j < nums.size(); j++) {
sum += nums[j];
// 注意这里使用while,每次更新 i(起始位置),并不断比较子序列是否符合条件
while (sum >= s) {
subLength = (j - i + 1); // 取子序列的长度
result = result < subLength ? result : subLength;
sum -= nums[i++]; // 这里体现出滑动窗口的精髓之处,不断变更i(子序列的起始位置)
}
}
// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
return result == INT32_MAX ? 0 : result;
}