返回
从LeetCode 掘金酱打卡挑战学习动态规划:妙用双指针计算雨水量
闲谈
2023-11-07 22:04:22
动态规划的魅力
动态规划是一种解决复杂问题的经典算法范式。其基本思想是将问题分解成一系列子问题,依次求解每个子问题,并将子问题的解存储起来,以便在求解后续子问题时复用。这种方法可以大大提高算法的效率,尤其适用于具有重叠子问题的场景。
双指针的妙用
双指针是一种简洁高效的算法技巧,常用于解决数组或链表等线性数据结构相关的问题。其基本思想是在数据结构的两端设置两个指针,然后以一定的方式移动这些指针,同时对数据结构进行操作。双指针算法通常可以将复杂度降低至线性和对数级别,显著提升算法效率。
问题建模与算法设计
雨水量计算问题可以抽象为一个柱状图模型。给定 n 个非负整数表示每个柱子的高度,我们需要计算当雨水落下时,柱状图中能接住多少雨水。为了解决这个问题,我们可以使用动态规划和双指针算法。
-
动态规划:
我们将问题分解成若干子问题,每个子问题对应柱状图中某一段连续的柱子。对于每个子问题,我们可以计算出该段柱子所能接住的雨水量。然后,我们将这些子问题的解累加起来,即可得到整个柱状图的雨水量。
-
双指针:
为了高效地求解子问题,我们可以使用双指针算法。我们从柱状图的两端分别设置两个指针,然后以一定的方式移动这些指针,同时计算子问题的解。这种方法可以将复杂度降低至线性和对数级别,显著提升算法效率。
代码示例
def trap(height):
"""
计算柱状图中能接住的雨水量
Args:
height (list): 柱状图每个柱子的高度
Returns:
int: 雨水量
"""
# 使用双指针
left, right = 0, len(height) - 1
# 初始化左右两侧的最大高度
left_max, right_max = height[left], height[right]
# 累计雨水量
total_water = 0
# 当左右指针未相遇时
while left < right:
# 如果左指针指向的柱子高度较低
if left_max < right_max:
# 移动左指针并更新最大高度
left += 1
left_max = max(left_max, height[left])
# 计算当前柱子能接住的雨水量
total_water += left_max - height[left]
# 否则右指针指向的柱子高度较低
else:
# 移动右指针并更新最大高度
right -= 1
right_max = max(right_max, height[right])
# 计算当前柱子能接住的雨水量
total_water += right_max - height[right]
# 返回累计雨水量
return total_water
结语
通过LeetCode 掘金酱打卡挑战,我们学习了如何运用动态规划和双指针算法解决雨水量计算问题。这种方法不仅可以帮助我们理解动态规划和双指针算法的原理,而且可以为我们解决其他类似问题提供思路。希望本文能帮助您提升算法技能,在面试和程序设计中取得优异成绩。