题目
题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/
给定一个含有 n
个正整数的数组和一个正整数 target
** 。**
找出该数组中满足其总和大于等于target
的长度最小的 子数组 [numsl, numsl+1, ..., numsr-1, numsr]
,并返回其长度**。**如果不存在符合条件的子数组,返回 0
。
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {}
};
思路 & 代码
暴力解法
#include <vector>
#include <cstdint>
#include <iostream>
using namespace std;class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int sum = 0;int subLength = 0;int result = INT32_MAX;// 需要<cstdint>头文件for(int i = 0; i < nums.size(); i++){sum = 0; // 是子序列的和,设置为0,用于下一个子序列的初始值for(int j = i; j < nums.size(); j++) {sum += nums[j];if (sum >= target){subLength = j - i + 1;result = result > subLength ? subLength : result;break; // 找到符合条件的子序列,就退出当前的 j 的for 循环。}}}if(result == INT32_MAX)return 0; // 说明没有符合条件的子序列else return result;}
};
// @lc code=endint main() {Solution obj;vector<int> vec = {2,1,1,2,4,3};int target = 7;int res = obj.minSubArrayLen(target, vec);cout << res << endl;
}
时间复杂度:O(n^2)
空间复杂度:O(1)
滑动窗口
滑动窗口:不断的调节子序列的起始位置和终止位置,从而得到想要的结果。
将暴力法中的两个for循环改成使用一个for循环实现搜索。
- 窗口内是什么?
- 满足其和 >= s 的长度最小的 连续 子数组
- 如何移动窗口的起始位置?
- 当前窗口的值 >= s,就要往前移动了
- 如何移动窗口的结束位置?
- 窗口的结束位置就是遍历数组的指针,也就是for循环里的索引
class Solution {
public:int minSubArrayLen(int target, vector<int>& nums) {int sum = 0;int subLength = 0;int result = INT32_MAX;// 需要<cstdint>头文件int i = 0;for(int j = 0; j < nums.size(); j++) {sum += nums[j];while (sum >= target){subLength = j - i + 1;result = result > subLength ? subLength : result;sum -= nums[i];i++;}}if(result == INT32_MAX)return 0; // 说明没有符合条件的子序列else return result;}
};
时间复杂度:O(n)
空间复杂度:O(1)
每个元素在滑动窗后进来操作一次,出去操作一次,每个元素都是被操作两次,所以时间复杂度是 2 × n 也就是O(n)