给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其总和大于等于 target 的长度最小的
子数组
[numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
示例 1:
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
示例 2:
输入:target = 4, nums = [1,4,4] 输出:1
示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1] 输出:0
提示:
1 <= target <= 1091 <= nums.length <= 1051 <= nums[i] <= 105
进阶:
- 如果你已经实现
O(n)时间复杂度的解法, 请尝试设计一个O(n log(n))时间复杂度的解法。
步骤 1:问题定义和条件分析
问题性质:
我们需要从一个包含 n 个正整数的数组 nums 中,找到一个最短的子数组,其元素的和至少为 target。然后返回该子数组的长度。如果不存在符合条件的子数组,返回 0。
输入条件:
target为正整数(1 <= target <= 10^9)。nums数组的长度为1 <= nums.length <= 10^5。nums中每个元素为正整数(1 <= nums[i] <= 10^5)。
输出条件:
- 满足和大于等于
target的最短子数组长度,若无符合条件的子数组,返回0。
潜在边界条件:
- 若
nums的元素总和小于target,则直接返回0。 - 若数组只有一个元素,则只需判断其是否大于等于
target。
步骤 2:解题思路
对于这个问题,以下算法设计是合适的:
滑动窗口法(双指针法):时间复杂度 O(n)
滑动窗口法适合处理这样的问题,因为它允许我们在遍历数组的过程中,动态地调整窗口范围,找到满足条件的最小子数组。
- 逻辑:
- 设定两个指针
left和right,初始化left和right均为0。 right指针向右移动(扩大窗口)来增加当前子数组的和,当子数组和满足>= target时,更新最小长度。- 然后移动
left指针(缩小窗口)以寻找更小的满足条件的子数组。
- 设定两个指针
- 步骤:
- 初始化
min_length为无穷大(表示未找到)。 - 使用
right指针遍历数组,逐步累加nums[right]。 - 当当前窗口和
sum >= target时,尝试缩小窗口,更新min_length。 - 继续移动
right,直到遍历完所有元素。 - 最终如果
min_length未更新,返回0,否则返回min_length。
- 初始化
这种方法能在 O(n) 时间内完成,因为每个指针最多只移动 n 次。
步骤 3:代码实现

代码说明:
- 初始化
min_length为INT_MAX,表示初始状态下未找到符合条件的子数组。 - 用
right指针遍历nums,累加当前窗口的和sum。 - 当
sum >= target时,尝试通过增加left指针来缩小窗口,并更新min_length。 - 若遍历结束后
min_length仍为INT_MAX,则返回0,否则返回min_length。
步骤 4:启发和优化思考
这个问题可以帮助我们认识到滑动窗口法的优势,尤其在处理连续子数组问题时,它能以 O(n) 的效率解决问题。通过利用窗口动态调整范围,我们可以避免暴力法中无效的重复计算。
优化思考
滑动窗口法已经是此问题的最优解,在 O(n) 的复杂度下完成。若进一步需要优化,可以考虑将计算逻辑与窗口缩小逻辑封装成函数,以提高代码的模块化和可读性。
步骤 5:实际应用示例
滑动窗口算法在实际中有很多应用场景,特别是在实时监控和数据流分析中。例如:
示例:网络数据包监控
在网络流量监控中,滑动窗口技术常用于检测异常流量。假设我们需要检测每分钟流量是否超过某个阈值(如 target)。可以使用滑动窗口算法在每秒更新网络流量,并找到超过流量阈值的最小时间窗口,从而及时预警潜在的网络攻击或异常流量。
实现方法
- 每秒记录当前流量,将数据记录在数组
nums中。 - 设定
target为异常流量阈值,用滑动窗口法实时检测是否存在总流量超过target的最短时间段。 - 若超过,则记录异常,触发告警。
这种方法应用滑动窗口算法可以显著减少数据存储和计算量,实现高效的实时监控和异常检测。
