LeetCode接雨水问题:双指针解法与优化策略
1. 问题背景与核心挑战接雨水是LeetCode题库中一道经典的Hard级别算法题编号42考察对数组处理、动态规划和双指针等核心编程思想的综合运用能力。题目描述如下给定n个非负整数表示的高度图每个柱子的宽度为1计算下雨后这些柱子能接住多少雨水。举个实际例子对于高度数组[0,1,0,2,1,0,1,3,2,1,2,1]对应的雨水存储情况如下图所示■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■其中■表示柱子空白部分表示存储的雨水。这个案例中总共能接6个单位的雨水。这道题之所以被归类为Hard难度主要因为需要将三维的雨水存储问题抽象为二维的高度计算多种解法之间存在显著的时间/空间复杂度差异边界条件的处理容易出错如最左/最右柱子最优解的双指针法需要巧妙的思路转换在实际面试中这道题出现在Amazon、Google、Microsoft等公司的技术面试中频率较高因为它能有效考察候选人的问题分析能力和算法思维。2. 暴力解法与初步优化2.1 直观的按列计算法最直观的解法是按列计算每个位置能存储的雨水量。对于数组中的每个元素height[i]它能存储的雨水量由其左右两侧最高柱子的较小值决定water[i] min(left_max, right_max) - height[i]如果这个值大于0则计入总水量。实现代码如下def trap_brute_force(height): total 0 n len(height) for i in range(1, n-1): left_max max(height[:i]) right_max max(height[i1:]) water min(left_max, right_max) - height[i] if water 0: total water return total注意这种方法的时间复杂度是O(n²)因为对每个元素都要扫描其左右两侧。在LeetCode上提交会因超时无法通过所有测试用例。2.2 预计算优化法我们可以通过预计算将左右最大值存储下来将时间复杂度优化到O(n)def trap_precompute(height): if not height: return 0 n len(height) left_max [0] * n right_max [0] * n left_max[0] height[0] for i in range(1, n): left_max[i] max(left_max[i-1], height[i]) right_max[-1] height[-1] for i in range(n-2, -1, -1): right_max[i] max(right_max[i1], height[i]) total 0 for i in range(n): water min(left_max[i], right_max[i]) - height[i] if water 0: total water return total这种方法虽然通过了时间限制但需要O(n)的额外空间存储左右最大值。在面试中面试官通常会进一步要求优化空间复杂度。3. 最优解双指针法3.1 算法思路双指针法能在O(n)时间复杂度和O(1)空间复杂度下解决问题。核心思想是使用左右两个指针从两端向中间移动维护左右两侧遇到的最大高度left_max和right_max每次移动较小max值的指针因为水量由较小值决定计算当前位置能存储的水量并累加def trap_two_pointers(height): if not height: return 0 left, right 0, len(height) - 1 left_max right_max 0 total 0 while left right: if height[left] height[right]: if height[left] left_max: left_max height[left] else: total left_max - height[left] left 1 else: if height[right] right_max: right_max height[right] else: total right_max - height[right] right - 1 return total3.2 为什么这种方法有效关键在于理解为什么可以移动较小max值的指针。假设height[left] height[right]此时left_max right_max一定成立因为right_max记录的是右侧历史最大值所以当前left位置的水量由left_max决定min(left_max, right_max) left_max即使右侧有更高的柱子也不会影响当前left位置的水量计算这种方法的精妙之处在于它动态地跟踪了可能影响水量的关键因素避免了不必要的计算。4. 边界条件与常见错误4.1 必须处理的特殊情况空数组或长度小于3的数组无法形成凹槽存储水单调递增/递减的数组无法存储水所有柱子高度相同无法存储水4.2 常见实现错误未正确处理边界柱子第一个和最后一个柱子不能储水在双指针法中错误地移动指针应该总是移动较小max值的指针忘记检查计算出的水量是否为正数在预计算方法中数组初始化错误应该初始化为当前高度提示在面试中建议先讨论这些边界情况展示你的全面思考能力。5. 算法扩展与变种5.1 3D接雨水问题LeetCode第407题Trapping Rain Water II将问题扩展到三维。这种情况下需要使用最小堆优先队列来跟踪边界高度时间复杂度为O(mn log(mn))。5.2 柱状图中最大矩形与此题相关的另一道经典题目是LeetCode 84柱状图中最大的矩形可以使用单调栈在O(n)时间内解决。5.3 实际工程应用这种算法思想可以应用于地理信息系统中的地形分析建筑设计中排水系统计算图像处理中的区域分割资源分配中的瓶颈分析6. 面试技巧与解题策略6.1 解题步骤建议先理解题意并举例说明画图很重要提出暴力解法并分析复杂度思考优化方向时间/空间逐步推导最优解可以从小规模例子开始讨论边界条件和特殊情况编写代码并测试6.2 面试官可能追问的问题如何证明你的算法是正确的如果柱子宽度不固定如[宽度高度]数组如何修改算法如何并行化这个算法以处理大规模数据如果要求实时计算滑动窗口内的储水量如何设计6.3 代码实现细节在实现双指针法时注意循环条件是left right不是先更新max值再计算水量移动指针时注意不要越界可以添加early termination条件如剩余柱子都低于当前max7. 性能对比与测试用例7.1 各解法性能对比方法时间复杂度空间复杂度LeetCode运行时间暴力法O(n²)O(1)超时预计算法O(n)O(n)60ms双指针法O(n)O(1)48ms单调栈法未讨论O(n)O(n)64ms7.2 推荐测试用例test_cases [ ([0,1,0,2,1,0,1,3,2,1,2,1], 6), # 标准案例 ([], 0), # 空数组 ([1], 0), # 单元素 ([1,2,3,4], 0), # 单调递增 ([4,3,2,1], 0), # 单调递减 ([3,1,2,1,3], 5), # 对称案例 ([5,4,3,2,1,2,3,4,5], 16), # V型案例 ([1,0,1,0,1], 2) # 交替案例 ]8. 不同语言的实现要点8.1 C实现注意事项int trap(vectorint height) { int left 0, right height.size() - 1; int left_max 0, right_max 0; int ans 0; while (left right) { if (height[left] height[right]) { height[left] left_max ? (left_max height[left]) : ans left_max - height[left]; left; } else { height[right] right_max ? (right_max height[right]) : ans right_max - height[right]; --right; } } return ans; }注意C中三元运算符的使用可以使代码更简洁但可读性会降低。8.2 Java实现要点public int trap(int[] height) { int left 0, right height.length - 1; int leftMax 0, rightMax 0; int res 0; while (left right) { if (height[left] height[right]) { if (height[left] leftMax) { leftMax height[left]; } else { res leftMax - height[left]; } left; } else { if (height[right] rightMax) { rightMax height[right]; } else { res rightMax - height[right]; } right--; } } return res; }Java实现中要注意数组越界检查建议先检查height.length是否为0。8.3 JavaScript实现技巧function trap(height) { let left 0, right height.length - 1; let leftMax 0, rightMax 0; let result 0; while (left right) { if (height[left] height[right]) { height[left] leftMax ? leftMax height[left] : result leftMax - height[left]; left; } else { height[right] rightMax ? rightMax height[right] : result rightMax - height[right]; right--; } } return result; }JS中可以使用箭头函数和更简洁的三元运算符但要注意浏览器兼容性。9. 实际工程中的优化考虑9.1 大数据量处理当柱子数量极大如处理地理数据时可以考虑分块处理将数据分成多个块分别计算后合并结果并行计算使用多线程或分布式计算处理不同区段流式处理对于实时数据流维护滑动窗口的最大值9.2 内存优化对于内存受限的环境使用双指针法避免存储额外数组如果必须存储预处理结果可以考虑使用更紧凑的数据结构对于极大数组可以只存储关键转折点而非全部数据9.3 数值精度问题当处理浮点数高度时注意比较时的精度误差使用epsilon比较累计水量时可能需要注意大数相加的问题考虑使用更高精度的数值类型如double而非float10. 学习资源与进阶题目10.1 推荐学习资料《算法导论》中的动态规划章节LeetCode的Two Pointers专题GeeksforGeeks上的雨水收集问题详解麻省理工开放课程《算法设计与分析》10.2 相关进阶题目LeetCode 11: 盛最多水的容器LeetCode 84: 柱状图中最大的矩形LeetCode 407: 接雨水 II3D版本LeetCode 755: 倒水问题10.3 可视化工具推荐LeetCode官方的问题可视化VisuAlgo算法可视化平台Python的matplotlib库绘制高度图使用Jupyter Notebook交互式调试掌握接雨水这类问题的解法不仅能帮助你在技术面试中表现出色更重要的是培养了将现实问题抽象为计算模型的能力。在实际工程中这种能力比记住特定算法更有价值。建议在理解基础解法后尝试自己推导出优化方案这样印象会更加深刻。

相关新闻

Supabase:开源BaaS平台,PostgreSQL驱动的全栈开发利器

Supabase:开源BaaS平台,PostgreSQL驱动的全栈开发利器

1. 项目概述:Supabase到底是什么?最近在Vibe Coding的社群里,Supabase这个名字被反复提及,频率高到让我这个老码农都忍不住侧目。很多刚入行的朋友,甚至一些有经验但主要用传统单体架构的开发者,都在问同一…

2026/8/9 8:17:49 阅读更多 →
滑模控制在车辆稳定性系统中的应用与优化

滑模控制在车辆稳定性系统中的应用与优化

1. 高速行驶中的车辆稳定性挑战当车速超过120km/h时,车辆动力学特性会发生显著变化。前轮转向角度的微小变化可能导致车身姿态的剧烈波动,这种非线性特性在紧急变道或强侧风条件下尤为明显。去年我在测试某款电动SUV时,就曾亲历过80km/h横风下…

2026/8/9 8:17:49 阅读更多 →
排队论实战:从Gen Con 2026现场74000名观众看大型活动容量规划

排队论实战:从Gen Con 2026现场74000名观众看大型活动容量规划

# 排队论实战:从Gen Con 2026现场74000名观众看大型活动容量规划8 月 6 日,世界最大桌游展会 Gen Con 2026 交出一份惊人的成绩单:超过 74000 名观众涌入美国印第安纳波利斯,连续第三届全部门票售罄,四天展期为当地带来…

2026/8/9 8:16:48 阅读更多 →

最新新闻

Django全栈开发:从零构建博客系统实战指南

Django全栈开发:从零构建博客系统实战指南

1. Django全栈开发入门:为什么选择博客系统作为练手项目?十年前我刚接触Django时,导师扔给我一个任务:"用Django做个博客系统"。当时觉得这太基础了,直到真正动手才发现,一个完整的博客系统几乎涵…

2026/8/9 9:27:17 阅读更多 →
网络性能指标全解析:从带宽、时延到吞吐量的诊断工具箱

网络性能指标全解析:从带宽、时延到吞吐量的诊断工具箱

你有没有过这样的经历:刚学完计算机网络,老师讲得头头是道,你也觉得每个概念都听懂了,但一到自己动手配置网络、排查问题,或者面试被问到“带宽和吞吐量有什么区别”时,脑子里却一片空白,只能模…

2026/8/9 9:27:17 阅读更多 →
现代时间管理:技术迭代与生命节奏的平衡之道

现代时间管理:技术迭代与生命节奏的平衡之道

1. 时间感知与生命节奏的当代解读 "天地转,光阴迫"这句充满张力的古语,在当代社会获得了全新的诠释维度。作为长期观察时间管理与社会节奏的实践者,我深刻感受到这句话正以三种显著方式重塑着现代人的生活图景: 1.1 技…

2026/8/9 9:27:17 阅读更多 →
从零构建完整项目开发流程:规划到交付实践

从零构建完整项目开发流程:规划到交付实践

1. 项目概述 作为一名从业多年的技术博主,我经常遇到这样的情况:一个看似简单的项目标题背后,往往隐藏着丰富的技术内涵和实践价值。今天我想和大家聊聊如何从零开始构建一个完整的项目开发流程,分享我在实际工作中的经验和心得。…

2026/8/9 9:26:17 阅读更多 →
从Jeff Dean与Demis Hassabis离职看AI工程化与科研转型

从Jeff Dean与Demis Hassabis离职看AI工程化与科研转型

Jeff Dean 离开 Google 创业,Demis Hassabis 卸任 Google DeepMind CEO:AI 巨头的“灵魂人物”为何出走? 最近,AI 圈被两条重磅消息刷屏:Google AI 的灵魂人物 Jeff Dean 宣布离职创业,而 DeepMind 的联合创…

2026/8/9 9:26:17 阅读更多 →
JMeter+Grafana+InfluxDB构建企业级全链路压测实时监控平台

JMeter+Grafana+InfluxDB构建企业级全链路压测实时监控平台

1. 项目概述与核心价值 最近在带团队做几个大促项目的全链路压测,一个老问题又浮出水面:压测报告生成慢,数据维度单一,团队里的产品、研发、运维同学围着一份静态的HTML报告,很难快速定位到性能瓶颈的根因。大家对着“…

2026/8/9 9:26:17 阅读更多 →

日新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/9 0:01:47 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/9 0:01:47 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/9 0:03:48 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/9 0:01:47 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/9 0:01:47 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/9 0:03:48 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/8 17:02:44 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/9 0:45:04 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/8 17:02:44 阅读更多 →