LeetCode #42 Trapping Rain Water
题目
解题思路
这题自己的思路没做出来,想法是从0开始寻找下一个与它高度相等或更高的方块,算出两方块围出来的矩形的面积,再减去其中的方块得到这一段的雨水,然后从这个更高或相等高度的方块开始继续找,若找到末尾就从这个方块的下一个位置开始重新找,直到最后。
Failed case: 4, 2, 3
其实算是对暴力破解的改进的一次尝试,整活没整出来...
这题有暴力破解法,动态规划法,栈法,双指针法,虽然是个hard,但还是很经典的,具体力扣都有,就不再赘述了。
代码
暴力破解
class Solution:
def trap(self, height: List[int]) -> int:
trapped = 0
for i in range(len(height)):
left_max, right_max = 0, 0
for j in range(i, -1, -1):
left_max = max(left_max, height[j])
for j in range(i, len(height)):
right_max = max(right_max, height[j])
trapped += min(left_max, right_max) - height[i]
return trapped
动态规划
class Solution:
def trap(self, height: List[int]) -> int:
if not len(height):
return 0
trapped = 0
left_max = [height[0]]
for i in range(1, len(height)):
left_max.append(max(left_max[i-1], height[i]))
right_max = [height[len(height)-1]]
for i in range(len(height)-2, -1, -1):
right_max.insert(0, max(right_max[0], height[i]))
for i in range(1, len(height)-1):
trapped += min(left_max[i], right_max[i]) - height[i]
return trapped
栈(较难理解)
class Solution:
def trap(self, height: List[int]) -> int:
ans, current = 0, 0
st = []
while current < len(height):
while len(st) and height[current] > height[st[-1]]:
top = st.pop()
if not len(st):
break
distance = current - st[-1] - 1
bounded_height = min(height[current], height[st[-1]]) - height[top]
ans += distance * bounded_height
st.append(current)
current += 1
return ans
双指针(较难理解)
class Solution:
def trap(self, height: List[int]) -> int:
left, right = 0, len(height) - 1
ans = 0
left_max, right_max = 0, 0
while left < right:
if height[left] < height[right]:
if height[left] >= left_max:
left_max = height[left]
else:
ans += left_max - height[left]
left += 1
else:
if height[right] >= right_max:
right_max = height[right]
else:
ans += right_max - height[right]
right -= 1
return ans