Skip to content

Commit 008dd55

Browse files
committed
chore: add daily leetcode post 42
1 parent 09de80d commit 008dd55

File tree

1 file changed

+123
-0
lines changed
  • app/docs/CommunityShare/Leetcode

1 file changed

+123
-0
lines changed
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
---
2+
title: 42.md
3+
date: '2025/3/27-19:56'
4+
tags:
5+
- - Python
6+
- - Answer
7+
abbrlink: 60fe0230
8+
---
9+
10+
# QUESTION:
11+
[42.md]()
12+
13+
# My Think:
14+
15+
滚瓜烂熟的一道题, 全部靠背诵. 但是昨天又理解了一下, 画了一个GIF图供我自己理解, 代码如下,
16+
17+
图片举例: `[0,1,0,2,1,0,1,3,2,1,2,1]`
18+
该题的核心思想其实就是木桶原理, 我们将最外面的两个柱子视作玛丽亚之墙, 这个时候我们忽略玛丽亚之墙内部的城墙, 那么最多是不是可以装`min(leftmax, rightmax)`这么高的水呢?
19+
也就是最短的柱子的水决定了它的"高度". 但是我们想知道最多能装多少水, 还需要一个宽度. 于是这个时候我们就一根一根柱子看, 也就是说我们计算每"1"个宽度能装多少水, 然后加起来即可.
20+
我们的左指针为`left`, 右指针为`right`, 我们再维护一个左边最高和右边最高.
21+
当我们到达最外面的玛丽亚之墙的时候, 左最高即为`leftmax`, 右最高即为`rightmax`, 这个时候我们是无法判断可以装多少水的.
22+
一直到`leftmost`!=`rightmost`的时候, 我们就可以判断了.
23+
24+
比如这一帧, 我们最多能装的是`leftmax`的水量, 即`2`, 但是因为我们这个时候左指针所在的柱子有一定高度`1`, 所以是`2-1=1`, 也就是我们能装`1`的水.
25+
如果我们比较的不是`leftmost``rightmost`, 而是`leftmax``rightmax`, 我们就无法确定说这一个柱子为什么能够兜得住水, 它之所以能兜住水,必然是<=`leftmax`
26+
27+
28+
This is a problem I’ve memorized inside out — totally muscle memory. But I revisited it yesterday and tried to actually understand it. I even made a GIF to help myself visualize what's happening. Here's the code:
29+
30+
Let's use the example: [0,1,0,2,1,0,1,3,2,1,2,1]
31+
32+
The core idea of this problem is basically the "bucket theory":
33+
We treat the two outermost bars as the "Walls of Maria" — and ignore the inner ones for now.
34+
If that's the case, then the max height of water we can hold is min(leftmax, rightmax).
35+
In other words, the shorter wall decides the water level.
36+
37+
But height alone isn’t enough — we also need width to compute the actual amount of water.
38+
So we look at each bar one by one, and calculate how much water we can trap on top of it, then sum it all up.
39+
40+
We use two pointers: left and right, and also keep track of the highest wall on the left (leftmax) and the highest wall on the right (rightmax).
41+
42+
When our pointer reaches the end of the string (or the two walls meet), that means we’ve gone through all the characters — that’s when we know we have a valid answer.
43+
44+
Take this specific frame as an example:
45+
46+
47+
At this point, the max water we can hold is leftmax = 2, but the current column has height 1, so we can trap:
48+
49+
`2 - 1 = 1` unit of water.
50+
51+
If we were comparing leftmax and rightmax directly, we wouldn’t know why this particular column can hold water. The only reason it can trap water is because its height is less than or equal to leftmax.
52+
53+
# Code:
54+
```python
55+
class Solution:
56+
def trap(self, height: list[int]) -> int:
57+
ans = leftmost = rightmost = 0
58+
left, right = 0, len(height) - 1
59+
while left < right:
60+
leftmost = max(leftmost, height[left])
61+
rightmost = max(rightmost, height[right])
62+
if leftmost <= rightmost:
63+
ans += leftmost - height[left]
64+
left += 1
65+
else:
66+
ans += rightmost - height[right]
67+
right -= 1
68+
return ans
69+
```
70+
```python
71+
import matplotlib.pyplot as plt
72+
import matplotlib.animation as animation
73+
import numpy as np
74+
75+
# Given height list for illustration
76+
height = [0,1,0,2,1,0,1,3,2,1,2,1]
77+
78+
# Initialize variables as in the function
79+
left, right = 0, len(height) - 1
80+
leftmax = rightmax = 0
81+
ans = 0
82+
83+
# For animation, store each frame's water level and pointers
84+
frames = []
85+
86+
# Simulate the logic and capture frames
87+
while left < right:
88+
leftmax = max(leftmax, height[left])
89+
rightmax = max(rightmax, height[right])
90+
water = [0] * len(height)
91+
if leftmax <= rightmax:
92+
trapped = max(0, leftmax - height[left])
93+
ans += trapped
94+
water[left] = trapped
95+
frames.append((height.copy(), water.copy(), left, right))
96+
left += 1
97+
else:
98+
trapped = max(0, rightmax - height[right])
99+
ans += trapped
100+
water[right] = trapped
101+
frames.append((height.copy(), water.copy(), left, right))
102+
right -= 1
103+
104+
# Create animation
105+
fig, ax = plt.subplots(figsize=(10, 5))
106+
107+
def update(frame):
108+
ax.clear()
109+
heights, water, l_ptr, r_ptr = frame
110+
indices = np.arange(len(heights))
111+
ax.bar(indices, heights, color='grey', edgecolor='black')
112+
ax.bar(indices, water, bottom=heights, color='blue', edgecolor='blue', alpha=0.6)
113+
ax.axvline(l_ptr, color='green', linestyle='--', label='Left Pointer')
114+
ax.axvline(r_ptr, color='red', linestyle='--', label='Right Pointer')
115+
ax.set_ylim(0, max(height) + 3)
116+
ax.set_title("Trapping Rain Water Animation")
117+
ax.legend()
118+
119+
ani = animation.FuncAnimation(fig, update, frames=frames, interval=500, repeat=False)
120+
121+
from IPython.display import HTML
122+
ani.save("trapping_rain_water.gif", writer="pillow", fps=2) # 保存为 GIF
123+
```

0 commit comments

Comments
 (0)