• 363. 接雨水


    363. 接雨水

    中文English

    给出 n 个非负整数,代表一张X轴上每个区域宽度为 1 的海拔图, 计算这个海拔图最多能接住多少(面积)雨水。

    Trapping Rain Water

    样例

    样例 1:

    输入: [0,1,0]
    输出: 0
    

    样例 2:

    输入: [0,1,0,2,1,0,1,3,2,1,2,1]
    输出: 6
    

    挑战

    O(n) 时间, O(1) 空间

    O(n) 时间, O(n) 空间也可以接受

    输入测试数据 (每行一个参数)如何理解测试数据?
    class Solution:
        '''
        大致思路:
        1.当前位置可以接雨水的数量 = min(左边最大值,右边最大值) - height(当前高度)
        2.得到当前位置左右两边最大值列表。最终得到结果。 
        '''
        def trapRainWater(self, heights):
            # write your code here
            #得到左,右最大值列表
            heights_l = [0] + heights + [0]
            left_l,right_l = [],[]
            left_max,right_max = 0,0
            for i in range(1,len(heights_l)-1):
                left_l.append(max(heights_l[:i+1]))
                right_l.append(max(heights_l[i:]))
            
            #开始计算各个位置可以接雨水的数量
            res = 0
            for j in range(len(heights)):
                res +=  min(left_l[j],right_l[j]) - heights[j]
            return res
            
    #result = Solution().trapRainWater([0,1,0,2,1,0,1,3,2,1,2,1])
    #print(result)

    注:lintcode未通过,代码时间超过限制,max(heights_l[:i+1],取最大值需优化

    优化之后:时间复杂度 O(n), 空间复杂度O(n)

    class Solution:
        """
        @param heights: a list of integers
        @return: a integer
        """
        '''
        大致思路:
        1.当前位置可以接雨水的数量 = min(左边最大值,右边最大值) - height(当前高度)
        2.得到当前位置左右两边最大值列表。最终得到结果。 
        '''
        def trapRainWater(self, heights):
            left_l = []
            right_l = []
            l_max,r_max = -sys.maxsize,-sys.maxsize
            for i in heights:
                l_max = max(i,l_max)
                left_l.append(l_max)
            
            for j in reversed(heights):
                r_max = max(j,r_max)
                right_l.append(r_max)
            
            right_l = right_l[::-1]
    
            res = 0
            for z in range(len(heights)):
                res += min(left_l[z],right_l[z]) - heights[z]
            return res

     相向型双向指针算法:时间复杂度O(n), 空间复杂度O(1)

    class Solution:
        """
        @param heights: a list of integers
        @return: a integer
        """
        '''
        大致思路:
        1.左指针 left_max < right_max
        不管当前位置在哪,只需要给出当前位置左边最大值,和右边假定最大值进行比较,如果left_max < right_max,则看左边是否可以接雨水
        left_max = max(left_max,当前位置高度)
        total += left_max - height  只有当前位置 [左边最大高度  右边假定最大高度] 中间才可以接雨水,left_max 来充当两边高度可以挡住的最小值
        2.右指针
        同上
        '''
        def trapRainWater(self, heights):
            if heights == []:
                return 0
    
            left_max,right_max = heights[0],heights[-1]
            total = 0
            left,right = 0,len(heights) - 1
            #在left < right 的时候成立,不能相等,否则left或者right会多走一步。(除非是left += 1放下面)
            while left < right:
                if left_max < right_max:#此时假定right_max 为右边可以挡住雨水的墙
                    #从第二个位置开始看,第一个位置接不了水
                    left += 1
                    left_max = max(left_max,heights[left])
                    total += left_max - heights[left] #如果左边有挡住的最大值墙,则可以接雨水
                    
                else:##此时假定左边left_max 为左边可以挡住的墙
                    #第二个位置开始看
                    right -= 1
                    right_max = max(right_max,heights[right])
                    total += right_max - heights[right]
            return total

    以当前位置为准,判断左右最大值的墙,计算当前位置可以接的雨水量

    class Solution:
        '''
        大致思路:
        1.左指针 left_max < right_max
        不管当前位置在哪,只需要给出当前位置左边最大值,和右边假定最大值进行比较,如果left_max < right_max,则看左边是否可以接雨水
        left_max = max(left_max,当前位置高度)
        total += left_max - height  只有当前位置 [左边最大高度  右边假定最大高度] 中间才可以接雨水,left_max 来充当两边高度可以挡住的最小值
        2.右指针
        同上
        '''
        def trapRainWater(self, heights):
            if heights == []:
                return 0
    
            left_max,right_max = heights[0],heights[-1]
            total = 0
            left,right = 0,len(heights) - 1
            #在left <= right 的时候成立,当两者刚好相等,则跳出循环
            while left <= right:
                if left_max < right_max:#此时假定right_max 为右边可以挡住雨水的墙
                    #以当前的位置为准,判断左边墙,出来在left += 1
                    left_max = max(left_max,heights[left])
                    total += left_max - heights[left] #如果左边有挡住的最大值墙,则可以接雨水
                    left += 1
                    
                else:##此时假定左边left_max 为左边可以挡住的墙
                    right_max = max(right_max,heights[right])
                    total += right_max - heights[right]
                    right -= 1
            return total
  • 相关阅读:
    玩个JAVA爬虫,没想玩大
    利用 Ruoyi 开发自己的业务管理系统__测试结构完成
    Vmware 和 VisualSVN-Server端口冲突
    Ruoyi的确不错,不知后续能否坚持 允许商用
    张勇:海底捞店长最高年薪600万!
    自己安装windows版本的Flink
    windows平台上运行Flink_转载于CSDN
    洛谷P3980 [NOI2008]志愿者招募
    线段树优化连边
    [HNOI2013]题解
  • 原文地址:https://www.cnblogs.com/yunxintryyoubest/p/12866541.html
Copyright © 2020-2023  润新知