码迷,mamicode.com
首页 > 其他好文 > 详细

leetcode 每日一题 42. 接雨水

时间:2020-05-24 16:43:12      阅读:50      评论:0      收藏:0      [点我收藏+]

标签:lis   元素   数组下标   ret   img   int   完成   循环   指针   

技术图片

暴力法:

思路:

从数组下标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. 接雨水

标签:lis   元素   数组下标   ret   img   int   完成   循环   指针   

原文地址:https://www.cnblogs.com/nilhxzcode/p/12951149.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!