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

滑动窗口与动态规划:解决无重复子串与股票收益问题

1. 算法实战:无重复字符的最长子串与含冷却期的股票最大收益

在算法面试和编程竞赛中,字符串处理和动态规划是两类经典问题。今天我想分享两个看似不同但都考验思维模式的题目解法:找出字符串中最长无重复字符的子串(Longest Substring Without Repeating Characters),以及带有卖出冷却期的股票买卖最大收益问题(Maximum Profit with Cooldown)。这两个问题分别来自LeetCode的第3题和第309题,在实际面试中出现频率极高。

第一个问题考察滑动窗口技巧的应用,需要在线性时间内完成字符串扫描;第二个问题则需要设计包含状态转移的动态规划方案,考虑交易规则的约束条件。虽然领域不同,但都体现了算法设计中"如何高效处理约束条件"的核心思想。下面我会结合代码示例和状态转移图,拆解这两个问题的解决思路和优化技巧。

2. 无重复字符的最长子串解析

2.1 问题定义与暴力解法

给定一个字符串s,要求找出其中不含有重复字符的最长子串的长度。例如"abcabcbb"的最长无重复子串是"abc",长度为3。

最直观的暴力解法是检查所有可能的子串:

def lengthOfLongestSubstring(s): max_len = 0 for i in range(len(s)): seen = set() for j in range(i, len(s)): if s[j] in seen: break seen.add(s[j]) max_len = max(max_len, len(seen)) return max_len

这种方法时间复杂度为O(n²),当字符串较长时性能堪忧。

2.2 滑动窗口优化方案

更高效的方案是使用滑动窗口配合哈希表记录字符位置:

def lengthOfLongestSubstring(s): char_index = {} left = max_len = 0 for right, char in enumerate(s): 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_len

这个算法的时间复杂度优化到O(n),空间复杂度O(min(m,n)),其中m是字符集大小。

关键技巧:当发现重复字符时,直接将窗口左边界跳到该字符上次出现位置的下一位,避免不必要的重复检查。

2.3 边界条件与测试用例

需要特别注意的边界情况包括:

  • 空字符串输入("") → 应返回0
  • 全相同字符("aaaaa") → 应返回1
  • 无重复字符("abcdef") → 应返回字符串长度
  • 混合情况("pwwkew") → 最长子串"wke"返回3

3. 含冷却期的股票买卖问题

3.1 问题建模

给定一个股票价格数组prices,其中prices[i]表示第i天的股票价格。设计算法计算最大利润,交易规则为:

  • 可以完成任意次交易
  • 卖出股票后需要等待一天才能再次买入(冷却期)
  • 不能同时进行多笔交易(必须卖出当前持有股票后才能再买入)

示例:prices = [1,2,3,0,2] 最大利润为3,对应交易序列:买入1,卖出2(利润1),冷却,买入0,卖出2(利润2)

3.2 动态规划状态设计

定义三个状态:

  • hold[i]:第i天结束时持有股票的最大利润
  • sold[i]:第i天结束时不持有股票且处于冷却期的最大利润
  • rest[i]:第i天结束时不持有股票且不处于冷却期的最大利润

状态转移方程:

hold[i] = max(hold[i-1], rest[i-1] - prices[i]) sold[i] = hold[i-1] + prices[i] rest[i] = max(rest[i-1], sold[i-1])

最终结果为max(sold[n-1], rest[n-1])

3.3 Python实现与空间优化

def maxProfit(prices): if not prices: return 0 hold = -prices[0] sold = 0 rest = 0 for i in range(1, len(prices)): prev_hold = hold hold = max(hold, rest - prices[i]) rest = max(rest, sold) sold = prev_hold + prices[i] return max(sold, rest)

通过变量复用将空间复杂度从O(n)优化到O(1)。

4. 算法对比与经验总结

4.1 解题模式差异

  • 滑动窗口:适用于子串/子数组类问题,通过维护窗口边界来避免重复计算
  • 状态机DP:适用于带约束条件的序列决策问题,通过明确定义状态来理清转移逻辑

4.2 常见错误排查

对于无重复子串问题:

  • 忘记更新字符最后出现位置
  • 窗口左边界移动时未考虑历史位置

对于股票问题:

  • 混淆hold和rest状态的转移条件
  • 初始化时未正确处理base case
  • 冷却期状态转移遗漏前一天卖出操作

4.3 性能优化技巧

  1. 滑动窗口问题可以先用暴力解法验证逻辑正确性
  2. 动态规划问题建议先画出状态转移图
  3. 对于空间敏感的场景,观察是否只需要前一个状态
  4. 使用断言(assert)验证边界条件

在实际面试中,建议先明确问题约束条件,再选择合适的数据结构和算法范式。这两个问题虽然领域不同,但都体现了算法设计中对问题约束条件的建模能力。

http://www.jsqmd.com/news/1370612/

相关文章:

  • PCB测试机如何决定电路板良率?产线升级的关键一问
  • 河北小型纸箱厂设备公司怎么选及本地服务参考 东光县鑫宇纸箱机械制造有限公司(河北服务中心) - 品牌优推
  • Unity NavMesh导航系统:从核心原理到高级优化实战指南
  • AI治理:从政策到实践,技术手段如何确保AI安全可控
  • UE5 StateTree入门:从零构建AI巡逻系统,告别行为树繁琐配置
  • Flutter+OpenHarmony构建高校资产管理系统实践
  • 海南落地 36 项低空基建,海岛无人机维保网点该如何布局
  • 2026年东莞广告挂绳供应厂家实力解析:展会吊绳/证件挂绳/促销挂绳源头工厂怎么选 - 优企名品
  • 动态规划结合单调队列优化解决补给站最小花费问题
  • 太原专业饭店公装公司推荐|餐饮门店装修设计施工
  • Redis核心特性与生产环境实践指南
  • 从文档存储到研发知识链路:Gitee Wiki 如何嵌入 DevSecOps 流程
  • Paddle-Agent开源框架:构建企业级AI智能体的全流程实践指南
  • 微信小程序双人协作厨房系统设计与实现
  • React自定义Hook设计原则与实战指南
  • Linux系统调用与futex机制深度解析
  • 论文降AI率失败原因与有效解决方案
  • AI工具Paperxie如何提升论文写作效率与质量
  • 现代网络安全三维防御体系构建与实践
  • AI模型数据隐私风险剖析:从Gemini事件看云端服务数据安全防护
  • 海外代理IP:数据抓取中代理IP的作用及应用技巧
  • CAD图形编辑核心:深入解析打断与合并命令的原理与应用
  • React 渲染性能优化与组件设计:部署前别漏掉这些配置
  • 仙桃市瓷砖空鼓维修上门推荐_2026江汉平原避坑攻略与合集_卫生间厨房阳台客厅墙砖地砖 - 雨婺虹修缮
  • Unity UGUI文本自适应:Content Size Fitter与自定义字体缩放实战
  • 基于协同过滤算法的SpringBoot+Vue美食推荐平台全栈实战
  • Unity Tilemap缩放全解析:三种方式对比与实战避坑指南
  • 深入掌握MFC控件:从消息映射到自定义绘制的实战指南
  • 做物联网项目,接口协议对接太麻烦?四个场景看懂HubPort AI原生物联网平台
  • 县城外卖平台小程序定制开发流程详解