当前位置: 首页 > news >正文

Minimum Size Subarray Sum:从 O(n²) 暴力到 O(n) 滑动窗口,我只改了 4 行

读完本文你将了解:滑动窗口的本质不是一行模板,而是对「最优子结构」的直觉 | AI 是怎么一步步从暴力解里挖出滑动窗口的 | 这道题在 Uber 动态定价系统里的真实映射


📋 题目

原题:给定一个正整数数组nums和一个正整数target,求出数组中和至少为 target 的最短连续子数组的长度。如果不存在这样的子数组,返回 0。

项目说明
输入target = 7, nums = [2,3,1,2,4,3]
输出2
约束1 ≤ target ≤ 10⁹,1 ≤ nums.length ≤ 10⁵,1 ≤ nums[i] ≤ 10⁵

最优解是 [4,3],长度 2。


💡 先问一个问题

如果让 ChatGPT 第一眼看这道题,它会怎么写?

它几乎必然会先用双重循环暴力遍历。

这不是 AI 笨——暴力解对应的是人类的直觉:枚举所有连续子数组,算和,选最短的。AI 的弱点也是人类的弱点:直觉往往是慢解法。

但 AI 有个好处:它会把每一步推理都摊开来。你能看到它从哪一步开始怀疑暴力解不够好,然后怎么找到更优方案。

🤖 第一版:暴力解,直觉的代价

最朴素的想法:两层循环枚举所有连续子数组:

defminSubArrayLen_brute(target,nums):n=len(nums)ans=n+1foriinrange(n):total=0forjinrange(i,n):total+=nums[j]iftotal>=target:ans=min(ans,j-i+1)breakreturnansifans<=nelse0

时间复杂度 O(n²),空间 O(1)。

AI 的直觉没错。但它枚举完 [2,3,1,2] 之后,下一轮从 [3,1,2,4] 开始——中间有大量重复计算。nums[1]+nums[2]+nums[3] 这个和,第一轮算过,第二轮又在算。

它会什么时候意识到这个问题?通常是在它自己测试一个长度为 10⁵ 的数组,然后卡住的时候。

暴力枚举
O(n²)

发现重复计算
subarray sum 被反复加

能不能复用?
右指针往右走时,
左指针也右移?

滑动窗口
O(n)

🧠 滑动窗口:让指针「滑」起来

核心直觉就一句话:

数组全是正数,右指针右移让和变大,左指针右移让和变小。我们只需要找到「刚好 ≥ target」的那个时刻。

算法流程:

  1. 右指针r向右滑,累加total
  2. 一旦total ≥ target,尝试把左指针l往右移(缩小窗口),同时更新最短长度
  3. 重复直到r走到头
defminSubArrayLen(target,nums):l=total=0ans=len(nums)+1forrinrange(len(nums)):total+=nums[r]whiletotal-nums[l]>=target:total-=nums[l]l+=1iftotal>=target:ans=min(ans,r-l+1)returnansifans<=len(nums)else0

为什么是 O(n)?左指针l和右指针r都只向右移动,每个元素最多被访问两次(一次r加进来,一次l移出去)。没有回头,没有重复计算。

窗口的「呼吸」节奏:

渲染错误:Mermaid 渲染失败: Parse error on line 7: ...U V -->|"否|r继续右移| R U --> W["更新最 ----------------------^ Expecting 'SEMI', 'NEWLINE', 'SPACE', 'EOF', 'SQS', 'SHAPE_DATA', 'AMP', 'STYLE_SEPARATOR', 'DOUBLECIRCLESTART', 'PS', '(-', 'STADIUMSTART', 'SUBROUTINESTART', 'VERTEX_WITH_PROPS_START', 'COLON', 'CYLINDERSTART', 'DIAMOND_START', 'TAGEND', 'TRAPSTART', 'INVTRAPSTART', 'START_LINK', 'LINK', 'LINK_ID', 'DOWN', 'DEFAULT', 'NUM', 'COMMA', 'NODE_STRING', 'BRKT', 'MINUS', 'MULT', 'UNICODE_TEXT', got 'PIPE'

☕ Java 实现

CSDN 用户里 Java 开发者最多,同样的思路,Java 版本:

publicintminSubArrayLen(inttarget,int[]nums){intl=0,total=0,ans=nums.length+1;for(intr=0;r<nums.length;r++){total+=nums[r];while(total-nums[l]>=target){total-=nums[l];l++;}if(total>=target){ans=Math.min(ans,r-l+1);}}returnans<=nums.length?ans:0;}

Python 和 Java 的唯一区别是 Java 没有 break,逻辑完全一致。

🔍 滑动窗口模式拆解

什么时候用滑动窗口?

三个条件同时满足:

条件说明本题是否满足
数据是数组/链表连续的结构
需要找连续子序列不是任意子集
子序列的性质是单调的加元素让某个值变大,删元素让某个值变小

如果三个条件都满足,滑动窗口大概率能用。如果第三条不满足(比如要找和等于某个值,且数组有负数),那就不是滑动窗口的问题了。

同类题:

  • LeetCode 3:无重复字符的最长字符串(滑动窗口 + 哈希表)
  • LeetCode 76:最小覆盖子串
  • LeetCode 340:至多包含 K 个不同字符的最长子串

🏗️ 真实产品场景:Uber 动态定价中的时间窗口

这道题在 Uber 的定价系统里有直接的映射。

Uber 的时间窗口定价问题:每个 5 分钟时间片都有供需数据。当某个时段的供需比达到阈值,系统要找出满足该阈值的最短连续时间区间

这和minSubArrayLen完全一致:正整数数组 = 供需比数据,target = 定价阈值,最短连续子数组 = 最短需要进入动态定价的时间区间。

Uber 2016 年的论文明确提到了用滑动窗口做时间序列的局部统计。这道题不是抽象的脑筋急转弯——它是 Uber 面试里用来验证候选人能不能把产品问题翻译成算法问题的经典题。

✅ 面试官的点评

写到什么程度算通过?

  • 通过线:能写出来 O(n) 的滑动窗口实现
  • 加分项
    • 能说出为什么双指针不会漏解(因为左指针只向右,不会跳过解)
    • 能处理全 0 或者全小于 target 的边界情况
    • 能指出 nums 包含负数时滑动窗口不再适用
  • 常见踩坑
    • while循环的条件写反(写成total < target而不是total - nums[l] >= target
    • ans的初始值设成 0,然后漏了无解的情况
    • 窗口缩小时没更新total

📊 同类题推荐

题目难度一句话思路
LC 3 无重复字符的最长字符串Medium滑动窗口 + 哈希表记录字符位置
LC 76 最小覆盖子串Hard滑动窗口 + 频次计数
LC 340 至多 K 个不同字符Medium滑动窗口 + 哈希表计数

来源说明:

  • ✅ 已验证:LeetCode 官方题解 + 本地 Python/Java 双语言实测
  • 📄 文档/论文:Uber Dynamic Pricing 论文 (2016)
http://www.jsqmd.com/news/1294703/

相关文章:

  • 长期更新软件:注册无广告WinRaR.v7.23压缩解压工具_二合一美化版
  • 5秒搞定麦克风静音:MicMute让你的Windows音频控制从未如此简单
  • 在Obsidian中一键导出PDF、Word和ePub:终极Pandoc插件完整指南
  • 终极免费AI音频增强教程:5分钟让你的语音清晰如新
  • 青少年离焦镜片选购指南:哪些品牌技术更扎实? 哪款更值得入手? - 探词产品观测室
  • LangChain 1.x升级指南:init_chat_model新特性解析
  • Unity开发必知:dataPath、streamingAssetsPath与persistentDataPath核心解析与实战指南
  • CTF应急响应实战:从流量分析到内存取证的综合安全能力训练
  • 基因载体全解析:从染色体结构到人工载体的生物技术应用
  • bit-bang时序被编译器优化破坏了怎么办
  • 用了“盖州德溢”才发现名声大也有不足?
  • 终端音频可视化神器:CAVA 让你的命令行随音乐起舞 [特殊字符]
  • 苏州帮制造业出海推荐服务公司怎么选?看这四点就够了 - GrowthUME
  • 代码题练习
  • 华为OD机试TLV解码:从协议原理到多语言实现详解
  • AI如何提升学术写作效率:智能框架与文献处理
  • ESP32 Arduino Core安装失败全解析:从网络问题到手动安装的终极解决方案
  • 2026河源美缝价格表|河源美缝哪家好?收费标准与避坑推荐 - GrowthUME
  • 光伏紧固件耐候性技术体系解析 江苏虎跃 30 年寿命保障底层逻辑
  • 嵌入式项目文档三件套——规则、清单、待办
  • 高速PCB设计中的绕等长:原理、实战与Altium Designer技巧
  • C++20 ranges自定义序列适配:哨兵与迭代器实践指南
  • 2026年沈阳活性炭选购攻略:沈民活性炭厂及国内优质企业盘点 - 品牌推荐达人
  • 半导体FAB制造术语体系:新人工程师快速入门指南
  • 2026年7月烟台芝罘区马桶地漏堵了怎么办?找本地金池管道疏通避坑指南 - 余生黄金回收
  • 2026 AIGEO 排名优化全攻略:从原理到实战,让 AI 优先引用你的内容
  • KRAS[G12D]突变体的靶向降解技术与临床转化
  • Python+Flask构建动漫数据可视化系统实战
  • 介观尺度电子输运:从量子效应到纳米器件设计实践
  • Python闭包与装饰器:提升代码质量的魔法工具