算法题(Python)数组篇 | 4.长度最小的子数组

算法题(Python)数组篇 | 4.长度最小的子数组

  • 一、题目描述
  • 二、题解
    • [2.1 解法一:暴力解法](#2.1 解法一:暴力解法)
    • [2.2 解法二:滑动窗口](#2.2 解法二:滑动窗口)

一、题目描述

给定一个含有n个正整数的数组和一个正整数target。找出该数组中满足其总和大于等于target的长度最小的子数组,并返回其长度。如果不存在符合条件的子数组,返回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 <= 10^9
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^4

二、题解

2.1 解法一:暴力解法

本题的暴力解法是采用两个for循环,然后不断地寻找符合条件的子序列,时间复杂度是 O ( n 2 ) O(n^2) O(n2),代码如下:

python 复制代码
class Solution:
	def minSubArrayLen(self, target: int, nums: List[int]) -> int:
		length = len(nums)
		min_len = float('inf')  # 子序列的长度
		
		for i in range(length):  # 设置子序列的起点i
			current_sum = 0
			for j in range(i, length):  # 设置子序列的终止位置j
				current_sum += nums[j]
				if current_sum >= target:  # 如果子序列的和超过了target,更新子序列的长度
					min_len = min(min_len, j - i + 1)
					break  # 一旦找到符合条件最短的子序列,则break
		# 如果min_len没有被赋值的话,返回0,说明没有符合条件的子序列
		return min_len if min_len != float('inf') else 0

暴力解法在力扣中是无法通过的,会超时。

2.2 解法二:滑动窗口

滑动窗口,就是不断地调节子序列的起始位置和终止位置,从而得出我们想要的结果。在暴力解法中,是一个for循环滑动窗口的起始位置,一个for循环为滑动窗口的终止位置,用两个for循环完成了一个不断搜索区间的过程。那么滑动窗口如何用一个for循环来完成这个操作呢?

首先要思考,如果用一个for循环,那么应该表示滑动窗口的起始位置,还是终止位置。如果只用一个for循环来表示滑动窗口的起始位置,那么如何遍历剩下的终止位置?此时难免再次陷入暴力解法的怪圈。所以只用一个for循环,那么这个循环的索引,一定是表示滑动窗口的终止位置。

示例:target=7, nums=2, 3, 1, 2, 4, 3

在本题中实现滑动窗口,需要确定如下三点:

  • 窗口内是什么?
  • 如何移动窗口的起始位置?
  • 如何移动窗口的结束位置?

窗口就是满足其和大于等于target的长度最小的连续子数组。

窗口的起始位置如何移动:如果当前窗口的值大于等于target了,窗口就要向前移动(也就是该缩小了)。

窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

解题的关键在于:窗口的起始位置如何移动,如图所示:

滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置,从而将 O ( n 2 ) O(n^2) O(n2)暴力解法降为 O ( n ) O(n) O(n)。

python 复制代码
class Solution:
	def minSubArrayLen(self, target: int, nums: List[int]) -> int:
		length = len(nums)
		left = 0
		right = 0
		min_len = float('inf')
		current_sum = 0   # 当前的累加值
		
		while right < length:
			current_sum += nums[right]
			while current_sum >= target:  # 当前的累加值大于目标值
				min_len = min(min_len, right - left + 1)
				current_sum = nums[left]
				left += 1
			right += 1
		return min_len if min_len != float('inf') else 0
相关推荐
张龙6871 小时前
uv 全面指南:比 pip 快 100 倍的 Python 包管理器,从安装到团队落地
后端·python
@HNUSTer2 小时前
Python数据可视化科技图表绘制系列教程(八)
python·数据可视化·科技论文·专业制图·科研图表
专注仿真2 小时前
问答大模型技术方案算法实现-熵权法融合算法 + 交叉编码器重排算法
人工智能·python·算法·语言模型·问答大模型关键算法·熵权融合算法·交叉编码器重排算法
满怀冰雪3 小时前
22-使用 PaddleClas 快速训练图像分类模型
人工智能·python·机器学习·分类·数据挖掘·paddlepaddle
gb42152873 小时前
python中Web应用服务器
开发语言·前端·python
地平线开发者3 小时前
量化为什么会有损失:从量化误差到精度下降
算法
手写码匠4 小时前
华为云Flexus+DeepSeek征文|Dify 多 Agent 会话管理与上下文工程实战:让智能体“记住该记住的,忘掉该忘掉的“
人工智能·深度学习·算法·aigc
2401_862880824 小时前
数据结构 --- 栈
c语言·数据结构·算法
致Great4 小时前
Qwen3.8-27B 接入 DSH 全流程实测:写代码、跑长任务,都没问题
算法
Tisfy5 小时前
LeetCode 3471.找出最大的几近缺失整数:三种情况判断
算法·leetcode·题解·分类讨论