LeetCode #42 Trapping Rain Water

题目

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
posted @ 2020-10-12 14:46  老鼠司令  阅读(86)  评论(0编辑  收藏  举报