题目来源:. - 力扣(LeetCode)
题目思路分析
给定一个整数数组 nums 和一个整数 target,题目要求找到数组中最短的连续子数组,其和大于等于 target,并返回其长度。如果不存在这样的子数组,则返回 0。
这个问题可以通过滑动窗口算法来解决。滑动窗口算法是一种用于处理数组问题的常用技巧,特别适用于在数组中寻找子数组或子串的问题。
解题思路如下:
- 初始化两个变量:
sum用于记录当前窗口内元素的和,k用于记录当前窗口的长度。 - 初始化
ans为数组长度加一(n+1),用于记录满足条件的最小子数组长度。这样做的目的是在后续比较时能够方便地判断是否存在满足条件的子数组。 - 使用一个循环遍历数组,每次将当前元素加入
sum,并增加k(窗口长度)。 - 在每次循环中,检查
sum是否大于等于target:- 如果是,说明找到了一个满足条件的子数组。此时,更新
ans为当前ans和k中的较小值,并尝试通过缩小窗口来寻找更短的子数组。 - 如果不是,继续扩展窗口(即继续遍历数组)。
- 如果是,说明找到了一个满足条件的子数组。此时,更新
- 缩小窗口的方法是通过减少
sum(减去窗口最左边的元素)并减少k(窗口长度减一)来实现的。 - 循环结束后,检查
ans是否仍为n+1,如果是,则说明不存在满足条件的子数组,返回 0;否则,返回ans。
代码实例及注解
实例:
#include <vector>
#include <algorithm> // 用于 std::min 函数(可选,因为这里可以手动比较)
class Solution {
public:
int minSubArrayLen(int target, std::vector<int>& nums) {
int n = nums.size(); // 记录数组长度
int ans = n + 1; // 初始化结果,设置为一个不可能达到的值(数组长度加一)
int sum = 0; // 记录当前窗口内元素的和
int k = 0; // 记录当前窗口的长度
// 遍历数组
for (int i = 0; i < n; i++) {
sum += nums[i]; // 将当前元素加入窗口和
++k; // 增加窗口长度
// 检查窗口和是否大于等于目标值
while (sum >= target) {
// 更新最小子数组长度
ans = std::min(ans, k); // 或者使用 ans = (ans < k) ? ans : k;
// 尝试缩小窗口
sum -= nums[i - k + 1]; // 减去窗口最左边的元素(注意下标计算)
--k; // 减少窗口长度
}
}
// 返回结果,如果不存在满足条件的子数组,则返回 0
return (ans == n + 1) ? 0 : ans;
}
};
注解:
std::vector<int>& nums:输入参数,一个整数类型的向量引用。int target:输入参数,目标值。int n = nums.size():记录数组的长度。int ans = n + 1:初始化结果变量,设置为一个不可能达到的值(数组长度加一),用于后续比较。int sum = 0:记录当前窗口内元素的和。int k = 0:记录当前窗口的长度。for (int i = 0; i < n; i++):遍历数组。sum += nums[i]:将当前元素加入窗口和。++k:增加窗口长度。while (sum >= target):当窗口和大于等于目标值时,执行循环体内的代码。ans = std::min(ans, k):更新最小子数组长度。sum -= nums[i - k + 1]:尝试缩小窗口,减去窗口最左边的元素(注意下标计算,避免数组越界)。--k:减少窗口长度。return (ans == n + 1) ? 0 : ans:返回结果,如果不存在满足条件的子数组,则返回 0。
知识点摘要
-
滑动窗口算法:一种用于处理数组或字符串中连续子数组/子串问题的常用技巧。通过维护一个窗口(即连续的子数组/子串),并动态地调整窗口的大小和位置来寻找满足条件的解。
-
数组和字符串的下标操作:在 C++ 中,数组和字符串的下标从 0 开始。在处理窗口最左边的元素时,需要注意下标的正确计算,以避免数组越界。
-
条件判断与更新操作:在算法中,经常需要根据当前的状态(如窗口和与目标值的关系)来更新变量(如最小子数组长度)或调整窗口的大小和位置。
-
算法的时间复杂度:该算法的时间复杂度为 O(n),其中 n 是数组的长度。因为每个元素最多被访问两次:一次是在窗口扩展时加入窗口和,另一次是在窗口缩小时被移除。
通过本文的讲解和代码实例,相信读者已经对如何使用滑动窗口算法求解最小子数组长度有了更深入的理解。
1733

被折叠的 条评论
为什么被折叠?



