LeetCode 接雨水问题解析与 Python 实现
接雨水(Trapping Rain Water)问题是一个经典的算法问题,通常出现在编程面试和在线评测中。问题描述如下:给定一个非负整数数组 height
,其中 height[i]
表示在位置 i
处的高度。计算在这些柱子之间可以接住多少雨水。
问题分析
接雨水的核心思想是,对于每一个位置 i
,我们需要找到左右两边的最高柱子(left_max 和 right_max),雨水的量等于 min(left_max, right_max) - height[i]
。不过,仅靠基础的循环实现,时间复杂度为 O(n^2),这对于较大的输入是不可接受的。
因此,我们通常采用双指针的方法。具体步骤如下:
- 初始化两个指针,
left
指向数组的开始,right
指向数组的结束。 - 用两个变量
left_max
和right_max
分别存储left
和right
指向的柱子的最大高度。 - 迭代直到
left
和right
相遇,根据left_max
和right_max
计算接水量。
代码实现
以下是使用 Python 实现接雨水问题的代码:
def trap(height):
if not height:
return 0
left, right = 0, len(height) - 1
left_max, right_max = height[left], height[right]
water_trapped = 0
while left < right:
if height[left] < height[right]:
left += 1
left_max = max(left_max, height[left])
water_trapped += left_max - height[left]
else:
right -= 1
right_max = max(right_max, height[right])
water_trapped += right_max - height[right]
return water_trapped
复杂度分析
- 时间复杂度: O(n),因为每个柱子仅被访问一次。
- 空间复杂度: O(1),仅使用了常数空间来存储变量。
甘特图表示时间复杂度分析
通过甘特图,我们可以清晰地查看算法的执行时间。
gantt
title 接雨水算法时间复杂度分析
dateFormat YYYY-MM-DD
section 遍历柱子
初始化指针 :a1, 2023-10-01, 1d
更新最大高度 :after a1 , 2d
计算接雨量 :after a1 , 3d
序列图
通过序列图,我们可以更好地理解每个步骤的执行顺序:
sequenceDiagram
participant U as 用户
participant F as 函数
U->>F: trap(height)调用
F->>F: 初始化指针和最大高度
F->>F: 进入while循环
alt height[left] < height[right]
F->>F: 更新left指针
F->>F: 更新left_max
F->>F: 计算接水量
else height[left] >= height[right]
F->>F: 更新right指针
F->>F: 更新right_max
F->>F: 计算接水量
end
F->>U: 返回接水量
结尾
接雨水问题不仅是算法和数据结构的一个有趣案例,更是面试中的常见考题。通过合理地分析和利用双指针方法,我们可以有效地解决问题。希望本文的探讨能为大家在解题过程中提供思路与启发。学习编程的过程中,编写和理解这些算法能帮助我们更好地应对面试及实际问题。