leetcode 每日一题 42. 接雨水

Posted nil_f

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 每日一题 42. 接雨水相关的知识,希望对你有一定的参考价值。

暴力法:

思路:

从数组下标1开始遍历到n-1,每当遍历一个元素时,分别寻找到当前元素开始左边和右边的最大值,用最大值中较小值减去当前元素值即为当前位置所能接到的雨水量,加入到结果res中,遍历完成后res即为接到雨水总量。

代码:

class Solution:
    def trap(self, height: List[int]) -> int:
        n = len(height)
        res = 0
        for i in range(1,n-1):
            left_max,right_max = 0,0
            for j in range(0,i+1):
                left_max = max(left_max,height[j])
            for k in range(i,n):
                right_max = max(right_max,height[k])
            res += min(left_max,right_max) - height[i]
        return res

 

动态规划:

思路:

在暴力法中,每遍历一个值,都要从左从右遍历寻找最大值。这里可以用动态法,通过两次遍历,先记录下每个位置的左右最大值,然后直接遍历一次的到结果。

代码:

class Solution:
    def trap(self, height: List[int]) -> int:
        if not height:
            return 0
        n = len(height)
        res = 0
        left_max = [0]*n
        right_max = [0]*n
        left_max[0] = height[0]
        right_max[n-1] = height[n-1]
        for i in range(1,n):
            left_max[i] = max(left_max[i-1],height[i])
        for j in range(n-2,-1,-1):
            right_max[j] = max(right_max[j+1],height[j])
        for k in range(1,n-1):
            res += min(right_max[k],left_max[k]) - height[k]
        return res

 

栈:

思路:

遍历列表每个元素,将元素下标压入栈中,在压入的时候,循环判断栈顶下标对应的值是否比当前下标对应的值小,如果小于当前下标对应的值,则将栈顶元素推出,同时找出新的栈顶下标对应值和当前下标对应值中的较大值,拿较大值减去推出下标对应的值,乘上当前下标和推出下标的差,然后进行累加,结果即为所能接雨水总量。

代码:

class Solution:
    def trap(self, height: List[int]) -> int:
        res = 0
        stack = []
        n = len(height)
        for i in range(n):
            while stack and height[i] > height[stack[len(stack)-1]]:
                popIndex = stack[len(stack)-1]
                stack.pop()
                if not stack:
                    break
                top = stack[len(stack)-1]
                distance = i - top - 1
                bound = min(height[i],height[top])-height[popIndex]
                res += distance*bound
            stack.append(i)
        return res 

 

双指针:

思路:

由暴力法和动态规划法可以看出,当前位置的雨水量由right_max和left_max中的较小值决定。我们可以定义两个指针left和right分别指向首尾,判断所指向元素大小,如果height[left]<height[right],则从左向右遍历,反之则从右向左遍历。在遍历过程中更新左右最大值,记录雨水量,可以通过一次遍历求得结果。

代码:

class Solution:
    def trap(self, height: List[int]) -> int:
        res = 0
        left,right = 0,len(height)-1
        left_max,right_max = 0,0
        while left<right:
            if height[left]<height[right]:
                if height[left]>=left_max:
                    left_max = height[left]
                else:
                    res += left_max-height[left]
                left += 1
            else:
                if height[right]>=right_max:
                    right_max = height[right]
                else:
                    res += right_max-height[right]
                right -= 1
        return res

 

以上是关于leetcode 每日一题 42. 接雨水的主要内容,如果未能解决你的问题,请参考以下文章

每日一题:42. 接雨水

《LeetCode之每日一题》:105.接雨水

LeetCode 每日一题「接雨水」

LeetCode:接雨水42

LeetCode 42 接雨水

LeetCode42题动态规划 - 接雨水