长度最小的子数组
- 一、题目
- 二、方法
- 1.暴力解法
- 2.滑动窗口
- 是什么
- 滑动窗口的起始位置
- 滑动窗口的结束位置
一、题目
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的 连续 子数组,并返回其长度。如果不存在符合条件的子数组,返回 0。
二、方法
1.暴力解法
双层for循环:
class Solution {
public:
int minSubArrayLen(int s, vector<int>& nums) {
int result = INT32_MAX; // 最终的结果
int sum = 0; // 子序列的数值之和
int subLength = 0; // 子序列的长度
for (int i = 0; i < nums.size(); i++) { // 设置子序列起点为i
sum = 0;
for (int j = i; j < nums.size(); j++) { // 设置子序列终止位置为j
sum += nums[j];
if (sum >= s) { // 一旦发现子序列和超过了s,更新result
subLength = j - i + 1; // 取子序列的长度
result = result < subLength ? result : subLength;
break; // 因为我们是找符合条件最短的子序列,所以一旦符合条件就break
}
}
}
// 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
return result == INT32_MAX ? 0 : result;
}
};
2.滑动窗口
是什么
就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果,这里也可以看作是双指针的一种方式,只是移动的方式更适合被称作为滑动窗口
滑动窗口的起始位置
起始位置会在当前窗口的值大于s后向前移动(缩小子序列的范围)
滑动窗口的结束位置
结束位置就是遍历数组的指针
var minSubArrayLen = function(target, nums) {
let start, end
start = end = 0
let sum = 0
let len = nums.length
//无限大
let ans = Infinity
while(end < len){
sum += nums[end];
while (sum >= target) {
ans = Math.min(ans, end - start + 1);
sum -= nums[start];
start++;
}
end++;
}
return ans === Infinity ? 0 : ans
};