news 2026/10/31 13:08:13

LeetCode接雨水问题解析:从暴力到双指针的优化

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode接雨水问题解析:从暴力到双指针的优化

1. 接雨水问题概述

接雨水(Trapping Rain Water)是LeetCode热题100中的一道经典困难题,编号42。这道题考察的是对数组特性的理解以及双指针、动态规划等算法的灵活运用。题目描述如下:给定n个非负整数表示每个宽度为1的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

我第一次接触这道题是在准备技术面试时,当时就被它巧妙的解法所吸引。看似简单的问题背后,隐藏着多种精妙的解决思路。在实际工作中,类似的问题也经常出现在资源分配、容量规划等场景中。

2. 问题分析与解法思路

2.1 暴力解法解析

最直观的解法是对于数组中的每个元素,我们找出下雨后水能达到的最高位置,等于两边最大高度的较小值减去当前高度的值。

def trap(height): res = 0 for i in range(1, len(height)-1): max_left = max(height[:i]) max_right = max(height[i+1:]) res += max(0, min(max_left, max_right) - height[i]) return res

这个解法的时间复杂度是O(n²),因为对于每个元素,我们都要向左和向右扫描整个数组来找到最大值。空间复杂度是O(1)。

注意:虽然这种解法能够通过部分测试用例,但在LeetCode上会因为超时无法通过所有测试,特别是当输入数组很大时。

2.2 动态规划优化

我们可以通过预计算来存储每个位置的左右最大值,避免重复计算。具体步骤如下:

  1. 创建两个数组left_max和right_max
  2. left_max[i]表示位置i左边的最大高度
  3. right_max[i]表示位置i右边的最大高度
  4. 遍历数组计算每个位置能接的雨水量
def trap(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(height[i], left_max[i-1]) right_max[-1] = height[-1] for i in range(n-2, -1, -1): right_max[i] = max(height[i], right_max[i+1]) res = 0 for i in range(n): res += min(left_max[i], right_max[i]) - height[i] return res

这种方法的时间复杂度降低到了O(n),因为我们只需要遍历数组三次。空间复杂度也是O(n),因为需要存储两个额外的数组。

2.3 双指针优化空间

我们可以进一步优化空间复杂度到O(1)。使用双指针法,只需要一次遍历:

def trap(height): if not height: return 0 left, right = 0, len(height)-1 left_max = right_max = 0 res = 0 while left < right: if height[left] < height[right]: if height[left] >= left_max: left_max = height[left] else: res += left_max - height[left] left += 1 else: if height[right] >= right_max: right_max = height[right] else: res += right_max - height[right] right -= 1 return res

这个解法的关键在于理解:当height[left] < height[right]时,左边的最大值决定了当前位置能接多少雨水,反之亦然。

3. 解法比较与选择

3.1 时间复杂度对比

解法类型时间复杂度空间复杂度适用场景
暴力解法O(n²)O(1)小规模数据
动态规划O(n)O(n)一般情况
双指针O(n)O(1)最优解

3.2 面试中的选择策略

在技术面试中,我建议按照以下顺序展示解题思路:

  1. 先提出暴力解法,说明其缺点
  2. 然后提出动态规划优化方案
  3. 最后展示双指针的最优解

这种展示方式能够体现你解决问题的思考过程,从简单到复杂,逐步优化。面试官通常更看重你分析问题和优化解决方案的能力,而不仅仅是写出最优解。

4. 常见错误与调试技巧

4.1 边界条件处理

很多同学在解决这个问题时容易忽略边界条件。以下是一些常见的边界情况:

  1. 空数组输入:应该返回0
  2. 单调递增或递减的数组:无法接住雨水
  3. 所有柱子高度相同:无法接住雨水

提示:在编写代码前,先考虑这些边界情况可以避免很多错误。

4.2 双指针法的常见误区

在使用双指针法时,容易犯以下错误:

  1. 移动指针的条件判断错误:应该比较height[left]和height[right],而不是left_max和right_max
  2. 忘记更新最大值:在移动指针前需要先更新当前边的最大值
  3. 循环条件错误:应该是left < right,而不是left <= right

4.3 调试技巧

当你的解法出现问题时,可以尝试以下调试方法:

  1. 打印中间变量:在关键步骤打印left_max、right_max等变量的值
  2. 使用小测试用例:先用简单的例子手动计算预期结果
  3. 可视化过程:在纸上画出柱状图,标注指针位置和计算结果

5. 实际应用与变种问题

5.1 实际应用场景

接雨水问题在实际中有很多应用,例如:

  1. 城市规划中的排水系统设计
  2. 农业中的灌溉系统规划
  3. 计算机图形学中的液体模拟
  4. 资源分配中的容量规划

5.2 相关变种问题

LeetCode上还有一些接雨水问题的变种,值得练习:

  1. 盛最多水的容器(LeetCode 11)
  2. 柱状图中最大的矩形(LeetCode 84)
  3. 接雨水II(LeetCode 407,3D版本)

6. 个人解题心得

在多次解决这个问题后,我总结出一些经验:

  1. 理解问题的本质是关键:接雨水问题实际上是找每个位置左右两边的"墙"
  2. 画图辅助理解:在纸上画出柱状图能帮助直观理解
  3. 从简单到复杂:先考虑如何计算一个位置的雨水量,再扩展到整个数组
  4. 注意边界条件:特别是数组为空或单调的情况
  5. 多练习变种问题:理解不同解法在不同场景下的适用性

我在面试中遇到这个问题时,通常会先和面试官确认输入的范围和边界条件,这不仅能展示你的严谨性,还能争取更多的思考时间。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/31 13:07:48

SpringBoot社区食材订购小程序开发实战

1. 项目背景与核心需求 社区食材订购小程序作为毕业设计选题&#xff0c;在当前线上线下融合的消费趋势下具有实际应用价值。这个SpringBoot项目需要解决三个核心问题&#xff1a; 社区居民对新鲜食材的便捷采购需求 小型农户/供应商的直销渠道搭建 社区团购模式的数字化管理…

作者头像 李华
网站建设 2026/10/31 13:07:48

2026端侧模型厂商选型指南:无界方舟Edge0与Audio8技术拆解

端侧模型这两年从“实验室里的演示”变成了“真能塞进设备里跑起来”的东西&#xff0c;变化速度比我预想的快不少。2024年那会儿&#xff0c;大家聊端侧还停留在“跑个7B量化模型&#xff0c;能出字就行”&#xff0c;到了2026年&#xff0c;评判标准已经完全不一样了——延迟…

作者头像 李华
网站建设 2026/10/31 13:07:47

AI编程智能体:从大模型到代码生成,普通程序员的杠杆革命

先说点实在的。“AI 编程智能体”这个词&#xff0c;最近两年被反复刷屏&#xff0c;从 GitHub Copilot 的自动补全&#xff0c;到 Cursor 这类 AI IDE 的对话式重构&#xff0c;再到能自己读仓库、跑测试、改代码的 Agent 形态&#xff0c;技术演进的速度比我预想中快得多。很…

作者头像 李华
网站建设 2026/10/31 13:05:06

大模型推理KV Cache显存优化:从PagedAttention到AI内存系统演进

大模型推理这件事&#xff0c;真正做过线上部署的人都有一个共同体会&#xff1a;模型权重加载完之后&#xff0c;真正的麻烦才刚刚开始。显存里那块被KV Cache吃掉的空间&#xff0c;往往比模型本身还大&#xff0c;而且它随着并发数和上下文长度动态膨胀&#xff0c;稍不留神…

作者头像 李华
网站建设 2026/10/31 13:04:47

AI模型训练核心技术解析与实践指南

1. AI模型训练技术全景解析 模型训练是AI开发的核心环节&#xff0c;决定了最终系统的性能上限。不同于传统的编程范式&#xff0c;AI模型训练是通过数据驱动的方式让机器自动学习规律的过程。这个过程涉及数据准备、模型选择、训练优化、评估调优等多个关键阶段。 在计算机视…

作者头像 李华
网站建设 2026/10/31 13:04:46

AI生成论文检测技术与学术伦理重建

1. 论文AI率骤降背后的学术危机 2023年那场学术地震至今让我记忆犹新。当时我负责审核的某核心期刊专题稿件中&#xff0c;AI生成内容占比竟高达78%&#xff0c;这个数字像一记重锤砸在每位编辑心上。最讽刺的是&#xff0c;有篇讨论"学术伦理"的论文&#xff0c;经检…

作者头像 李华