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

LeetCode刷题保姆级攻略:用滑动窗口秒杀「无重复字符的最长子串」和「最小覆盖子串」

LeetCode滑动窗口算法精讲从暴力解法到最优解的思维跃迁滑动窗口算法是解决字符串和数组子序列问题的利器尤其适合处理最长子串、最小覆盖子串这类经典问题。很多开发者在初次接触这类题目时往往会陷入暴力解法的思维定式导致代码效率低下。本文将带你突破这一瓶颈掌握滑动窗口的核心思想与实战技巧。1. 滑动窗口的本质与适用场景滑动窗口算法本质上是一种双指针技巧的高级应用它通过维护一个动态变化的窗口来避免不必要的重复计算。想象你在观察一个不断滑动的窗户透过这个窗户你只能看到数组或字符串的一部分——这正是算法名称的由来。适用滑动窗口的问题通常具有以下特征问题涉及数组/字符串的连续子序列需要寻找满足特定条件的最大/最小窗口暴力解法通常需要O(n²)或更高时间复杂度例如在「无重复字符的最长子串」问题中我们需要找到一个字符串中不包含重复字符的最长连续子串。暴力解法会检查所有可能的子串而滑动窗口可以将时间复杂度优化到O(n)。提示当题目中出现子串、子数组、连续等关键词时优先考虑滑动窗口解法。2. 滑动窗口的通用框架与实现所有滑动窗口问题都遵循相似的基本框架。下面是一个Python实现的通用模板def sliding_window(s: str) - int: left 0 # 窗口左边界 result 0 # 存储最终结果 window {} # 用于记录窗口内元素的状态 for right in range(len(s)): # 右指针遍历整个字符串 # 1. 将当前字符加入窗口 char s[right] window[char] window.get(char, 0) 1 # 2. 当窗口不满足条件时收缩左边界 while window_needs_shrink(window): left_char s[left] window[left_char] - 1 if window[left_char] 0: del window[left_char] left 1 # 左指针右移 # 3. 更新结果 result max(result, right - left 1) return result这个模板包含了滑动窗口算法的三个关键步骤扩展窗口右指针移动将新元素纳入窗口收缩窗口当窗口不满足条件时左指针移动以缩小窗口更新结果在每次窗口满足条件时记录当前最优解实际应用时需要根据具体问题调整window_needs_shrink的判断条件窗口数据的存储方式哈希表、计数器等结果更新的逻辑3. 经典问题解析无重复字符的最长子串让我们用上述框架解决LeetCode第3题「无重复字符的最长子串」。题目要求找到给定字符串中不含有重复字符的最长子串的长度。3.1 问题分析输入字符串abcabcbb 预期输出3abc是最长无重复子串关键点需要检测窗口内是否有重复字符当出现重复时需要收缩窗口直到重复被消除记录过程中出现的最大窗口大小3.2 代码实现def lengthOfLongestSubstring(s: str) - int: left 0 max_len 0 char_index {} # 存储字符及其最后出现的位置 for right in range(len(s)): char s[right] # 如果字符已存在且位置在窗口内需要收缩窗口 if char in char_index and char_index[char] left: left char_index[char] 1 # 更新字符的最新位置 char_index[char] right # 计算当前窗口长度 max_len max(max_len, right - left 1) return max_len3.3 复杂度分析时间复杂度O(n)每个字符最多被访问两次右指针和左指针各一次空间复杂度O(min(m, n))其中m是字符集大小n是字符串长度优化点使用数组代替哈希表可以进一步优化常数时间特别是当字符集已知且较小时如仅包含ASCII字符。4. 进阶问题最小覆盖子串LeetCode第76题「最小覆盖子串」是滑动窗口的经典难题。题目要求在字符串s中找到包含字符串t所有字符的最小子串。4.1 问题分析输入s ADOBECODEBANC, t ABC 输出BANC关键点需要统计t中所有字符的出现次数窗口需要包含t的所有字符且次数不少于t中的次数需要在满足条件的窗口中寻找最小的那个4.2 代码实现from collections import defaultdict def minWindow(s: str, t: str) - str: if not s or not t or len(s) len(t): return # 初始化需求字典 need defaultdict(int) for c in t: need[c] 1 need_cnt len(t) # 总共需要的字符数 left 0 min_len float(inf) result for right in range(len(s)): char s[right] if char in need: if need[char] 0: need_cnt - 1 need[char] - 1 # 当窗口满足条件时 while need_cnt 0: # 更新最小窗口 if right - left 1 min_len: min_len right - left 1 result s[left:right1] # 尝试收缩左边界 left_char s[left] if left_char in need: need[left_char] 1 if need[left_char] 0: need_cnt 1 left 1 return result4.3 解题技巧使用计数器need_cnt跟踪还需要匹配的字符总数避免每次检查整个需求字典负值处理当窗口中有多余的所需字符时need字典中的值可以为负结果更新时机仅在need_cnt 0时考虑更新结果5. 滑动窗口的变体与优化滑动窗口算法在实际应用中存在多种变体掌握这些变体可以解决更复杂的问题。5.1 固定大小的滑动窗口有些问题的窗口大小是固定的如「找到字符串中所有字母异位词」LeetCode 438。这种情况下窗口的左右指针总是同步移动。def findAnagrams(s: str, p: str) - List[int]: if len(s) len(p): return [] p_count [0] * 26 s_count [0] * 26 result [] # 初始化p的字符计数 for c in p: p_count[ord(c) - ord(a)] 1 # 初始化滑动窗口 for i in range(len(p)): s_count[ord(s[i]) - ord(a)] 1 if s_count p_count: result.append(0) # 滑动窗口 for i in range(len(p), len(s)): # 移除左边界的字符 left_char s[i - len(p)] s_count[ord(left_char) - ord(a)] - 1 # 添加右边界的字符 right_char s[i] s_count[ord(right_char) - ord(a)] 1 if s_count p_count: result.append(i - len(p) 1) return result5.2 多指针滑动窗口对于更复杂的问题可能需要维护多个指针或状态。例如「水果成篮」LeetCode 904问题需要跟踪窗口中的两种不同类型。def totalFruit(fruits: List[int]) - int: basket {} left 0 max_fruits 0 for right in range(len(fruits)): fruit fruits[right] basket[fruit] basket.get(fruit, 0) 1 # 当篮子中有超过2种水果时 while len(basket) 2: left_fruit fruits[left] basket[left_fruit] - 1 if basket[left_fruit] 0: del basket[left_fruit] left 1 max_fruits max(max_fruits, right - left 1) return max_fruits5.3 前缀和与滑动窗口结合当问题涉及子数组和时可以结合前缀和技巧。例如「和至少为K的最短子数组」LeetCode 862需要使用单调队列优化滑动窗口。6. 常见错误与调试技巧即使掌握了滑动窗口的基本思想实际编码中仍会遇到各种问题。以下是几个常见错误及解决方法错误1窗口收缩条件不正确症状程序无法找到正确解或陷入无限循环。解决方法仔细分析问题条件确保收缩条件准确反映问题要求。可以手动模拟小例子验证。错误2结果更新时机不当症状程序能找到部分解但不是最优解。解决方法明确何时应该更新结果——通常在窗口满足条件时但有时需要在收缩过程中更新。错误3数据结构选择不当症状算法时间复杂度过高无法通过大规模测试。解决方法根据问题特点选择高效的数据结构如用数组代替哈希表处理有限字符集问题。调试技巧打印窗口状态在每次指针移动时打印窗口内容使用小测试用例手动验证算法是否正确边界条件检查空输入、所有元素相同等特殊情况# 调试示例在滑动窗口代码中添加打印语句 def debug_sliding_window(s): left 0 result 0 window set() for right in range(len(s)): char s[right] print(f\n右指针移动到 {right}, 字符 {char}) while char in window: print(f 重复字符 {char}, 左指针从 {left} 移动到 {left1}) window.remove(s[left]) left 1 window.add(char) print(f当前窗口: {window}, 长度: {right - left 1}) result max(result, right - left 1) return result7. 滑动窗口与其他算法的比较理解滑动窗口与其他相似算法的区别有助于在解题时选择最合适的工具。算法适用场景时间复杂度空间复杂度特点滑动窗口连续子序列问题O(n)O(k)双指针动态维护窗口动态规划子序列问题不要求连续O(n²)O(n)记忆化递归解决重叠子问题分治法可分割的复杂问题O(nlogn)O(logn)将问题分解为更小的子问题暴力枚举所有问题O(n²)或更高O(1)简单但效率低何时选择滑动窗口问题涉及数组/字符串的连续子序列需要优化暴力解法的时间复杂度可以定义明确的窗口条件满足/不满足滑动窗口的局限性不适用于非连续子序列问题对于某些复杂条件可能难以设计收缩条件需要额外的空间存储窗口状态在实际面试中我经常先考虑暴力解法然后分析是否有重叠计算可以通过滑动窗口优化。这种从简单到复杂的思考过程也更容易向面试官展示。

相关文章:

LeetCode刷题保姆级攻略:用滑动窗口秒杀「无重复字符的最长子串」和「最小覆盖子串」

LeetCode滑动窗口算法精讲:从暴力解法到最优解的思维跃迁 滑动窗口算法是解决字符串和数组子序列问题的利器,尤其适合处理"最长子串"、"最小覆盖子串"这类经典问题。很多开发者在初次接触这类题目时,往往会陷入暴力解法…...

SEO研究是否需要进行A-B测试

SEO研究是否需要进行A/B测试 在当今竞争激烈的数字市场中,搜索引擎优化(SEO)已经成为企业提升网站流量和品牌知名度的重要手段。随着SEO领域的不断发展,许多企业开始质疑:是否需要在SEO研究中进行A/B测试。本文将深入…...

超越目标空间:多模态多目标优化算法的决策空间评价指标深度解析

1. 为什么我们需要关注决策空间的评价指标? 在传统的多目标优化问题中,我们通常只关注目标空间的性能表现。比如常见的IGD(反转世代距离)和HV(超体积)指标,它们能够很好地衡量解集在目标空间的分…...

Neovim文本编辑器

链接:https://pan.quark.cn/s/ce457be69098Neovim是一款基于Vi编辑器的文本编辑器,Neovim是Vim的一个分支,旨在解决Vim的一些缺点并提供额外特性。Neovim具有更好的性能和稳定性,支持异步插件和脚本,改进了对现代用户界…...

多模态扩展:OpenClaw对接Qwen3-14B镜像实现图文混合处理

多模态扩展:OpenClaw对接Qwen3-14B镜像实现图文混合处理 1. 为什么需要多模态能力扩展 去年我在整理技术文档时,发现纯文本处理已经无法满足实际需求。当需要从截图提取错误日志、给产品原型图生成说明文档时,不得不反复在多个工具间切换。…...

别让Liquid Glass拖慢你的App!给uni-app开发者的iOS 26动画优化清单(含代码示例)

别让Liquid Glass拖慢你的App!给uni-app开发者的iOS 26动画优化清单(含代码示例) 最近在开发者社区里,不少同行都在吐槽iOS 26的动画性能问题。特别是那些采用了新Liquid Glass设计的应用,在旧款iPhone上运行时&#x…...

NAT地址映射表详解:如何看懂并优化你的网络转换效率

NAT地址映射表深度解析:从原理到实战优化的完整指南 当你打开手机浏览网页时,是否想过内网设备如何通过有限的公网IP与全球互联网通信?这背后隐藏着一项关键技术——NAT地址转换。不同于教科书式的概念罗列,我们将从真实网络工程师…...

HTML函数在ARM架构设备能运行吗_ARM硬件兼容性测试【详解】

HTML 本身没有函数,它不是编程语言;真正运行在 ARM 设备上的是 JavaScript、后端代码或 WebAssembly,主流浏览器和 Node.js 均原生支持 ARM 架构,问题多出在依赖的二进制模块或 wasm 文件架构不匹配。HTML函数?浏览器里…...

MGC3130电场式三维手势控制器原理与工程实践

1. MGC3130:全球首款电场式三维手势与轨迹追踪控制器深度解析1.1 技术定位与工程价值MGC3130 是由Microchip(原Atmel)推出的全球首款基于电场(E-field)传感原理的三维空间轨迹追踪与手势识别专用控制器。其核心突破在于…...

Flutter鸿蒙应用开发:数据分享功能实现

🔥Flutter鸿蒙应用开发:数据分享功能实现(macOSDevEco Studio) 欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net 📄 文章摘要 本文为Flutter for OpenHarmony跨平台应用开发系列实…...

OpenClaw问题排查大全:百川2-13B-4bits量化模型接入常见错误

OpenClaw问题排查大全:百川2-13B-4bits量化模型接入常见错误 1. 问题排查前的准备工作 在开始排查OpenClaw与百川2-13B-4bits量化模型对接的问题前,我们需要先确认几个基础环境要素。这些准备工作往往能帮我们快速排除50%以上的低级错误。 首先检查Op…...

2025届学术党必备的六大降重复率助手推荐

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 提高人工智能生成内容即AIGC的检测难度,关键之处在于增强文本的自然特性与个性化…...

如何比较不同注册商的域名注册价格_如何查看域名的SEO数据和排名信息

如何比较不同注册商的域名注册价格 在互联网时代,域名已经成为网站的“门面”,是网站建设的重要一步。不同注册商的域名注册价格差异较大,如何在保证性价比的前提下选择合适的注册商成为了一个重要的问题。本文将详细探讨如何比较不同注册商…...

OpenClaw多模态研究助手:千问3.5-35B-A3B-FP8实现论文图表解析与笔记生成

OpenClaw多模态研究助手:千问3.5-35B-A3B-FP8实现论文图表解析与笔记生成 1. 为什么需要多模态研究助手 作为一名经常需要阅读前沿论文的研究者,我长期被两个问题困扰:一是PDF论文中的图表数据提取费时费力,二是阅读过程中的碎片…...

腾讯云ICP备案:变更主体备案准备

腾讯云ICP备案:变更主体&备案准备一、变更主体适用场景已经成功办理备案的网站/APP,支持备案主体信息的变更申请。当备案主体信息发生变化时,建议及时办理备案变更,避免影响业务运行,可直接通过腾讯云备案控制台办…...

6款AI论文改写工具,智能降重与语言润色,有效减少重复率。

开头总结工具对比(技能4) �� 为帮助学生们快速选出最适合的AI论文工具,我从处理速度、降重效果和核心优势三个维度,对比了6款热门网站,数据基于实际使用案例: 工具名称 处理速度 降…...

6款AI论文降重软件,智能改写与优化,显著提升原创度。

开头总结工具对比(技能4) �� 为帮助学生们快速选出最适合的AI论文工具,我从处理速度、降重效果和核心优势三个维度,对比了6款热门网站,数据基于实际使用案例: 工具名称 处理速度 降…...

IIS配置HTTPS如何多个二级域名连接!

一、前言 我们可能多个域名指向同一个主机,但我们配置HTTPS之后,发现仅配置的一个域名可用; 我们仅申请了一个二级域名的证书,如:www.xxx.com;(个人免费证书) 我的另外一个二级域名&#xff…...

OpenClaw安全实践:Phi-3-mini-128k-instruct本地化部署的3个关键配置

OpenClaw安全实践:Phi-3-mini-128k-instruct本地化部署的3个关键配置 1. 为什么需要关注OpenClaw的安全配置? 去年夏天,我在整理个人财务数据时突发奇想:能否用AI自动生成月度支出分析报告?这个看似简单的需求&#…...

C++27反射工具链现状全景图(2024Q3):Boost.PFR停更、cpp-reflect弃坑、std::reflect成为唯一工业级选择?

第一章:C27静态反射的标准化演进与战略意义C27静态反射(Static Reflection)正从实验性提案走向核心语言特性,其标准化进程标志着C元编程范式的根本性跃迁。不同于C20的std::is_same_v等类型特征或C23的std::type_identity_t&#…...

GLM-OCR硬件优化指南:为GPU部署调整显存与算力配置

GLM-OCR硬件优化指南:为GPU部署调整显存与算力配置 如果你正在尝试部署GLM-OCR模型,是不是也遇到过这样的困惑:明明选了看起来不错的GPU,但推理时要么爆显存,要么速度慢得让人着急,钱花了效果却没达到预期…...

开发者效率提升:OpenClaw+Phi-3-vision-128k-instruct自动生成代码注释与文档

开发者效率提升:OpenClawPhi-3-vision-128k-instruct自动生成代码注释与文档 1. 为什么需要自动化代码文档维护 作为一个长期与代码打交道的开发者,我发现自己总在重复做一件"重要但不紧急"的事——写注释和更新文档。每次写完核心逻辑后&am…...

Linux CFS 的调度周期调整:任务数量对调度粒度的影响

一、简介1.1 背景与重要性在实时嵌入式系统、高性能计算(HPC)和云计算基础设施中,Linux 完全公平调度器(Completely Fair Scheduler, CFS)是默认的进程调度算法。CFS 自 Linux 2.6.23 版本引入以来,一直是 …...

32-字体反爬

本文需要借助工具:fontcreator,或者在线网站:字体设计在线网站 字体反爬介绍 字体反爬是网站常用的前端反爬手段,核心逻辑是用自定义字体文件替代明文文本,爬虫自动化也无法拿到正确的明文数据 字体反爬原理 本文主…...

无障碍技术实践:OpenClaw+Phi-3-vision-128k-instruct为视障用户描述图片

无障碍技术实践:OpenClawPhi-3-vision-128k-instruct为视障用户描述图片 1. 项目背景与动机 去年冬天的一次地铁站经历让我萌生了这个想法。当时我看到一位视障朋友在站台反复用盲杖试探前方障碍物,而墙上明明贴着"施工绕行"的警示海报。这个…...

三种常见AC/DC转换方案详解与选型指南

1. 交流转直流方案概述在电子设备设计中,将交流电转换为直流电是最基础也是最重要的环节之一。作为一名硬件工程师,我在过去十年里接触过各种AC/DC转换方案,从简单的阻容降压到复杂的开关电源设计。这些方案各有特点,适用于不同的…...

已登CVPR&Nature子刊,小波变换+深度学习杀疯了 !!

融合小波变换的深度学习模型是当前的研究热点之一,这个交叉领域热度高、前景好、创新空间大,只要选对结合点和方法,冲顶会顶刊问题不大。比如Transformer、GNN、KAN、CNN、mamba等,就是目前比较前沿而且热度很高的结合方式&#x…...

AUTOSAR Ethernet Stack深度解析,手把手实现SOME/IP序列化、DDS桥接与时间同步校准

第一章:AUTOSAR以太网协议栈架构概览AUTOSAR以太网协议栈是面向汽车电子域控制器与中央计算平台的关键通信基础设施,其设计严格遵循AUTOSAR Classic Platform规范(R21-11及后续版本),在保持与传统CAN/LIN协议栈统一配置…...

Shell_命令语法、管道和重定向详细介绍

Shell 命令语法、管道和重定向详细介绍 一、Shell 命令基本语法 1.1 命令结构 命令 [选项] [参数]命令:要执行的程序选项:修改命令行为的标志(通常以 - 或 -- 开头)参数:命令操作的对象 示例: ls-l /ho…...

产业园区如何搭建智能化技术服务平台?

观点作者:科易网-国家科技成果转化(厦门)示范基地 一、现状概述:传统产业园区服务的效能瓶颈与转型需求 产业园区作为区域经济发展的重要载体和创新要素集聚的核心区域,近年来在国家创新驱动发展战略的引领下取得了显著…...