zoukankan      html  css  js  c++  java
  • leetcode42

     1 class Solution:
     2     def calLeft(self,height,rightval,left,right):
     3         if left>=right:
     4             return 0
     5         sums = 0
     6         maxindex=0
     7         maxval=-1
     8         for i in range(left,right):
     9             cur = height[i]
    10             if cur>maxval:
    11                 maxval=cur
    12                 maxindex=i
    13         waterlevel = min(maxval,rightval)
    14         for i in range(maxindex+1,right):
    15             sums += max(0,waterlevel-height[i])
    16         sums += self.calLeft(height,waterlevel,0,maxindex)
    17         return sums
    18     def calRight(self,height,leftval,left,right):
    19         if left>=right:
    20             return 0
    21         sums = 0
    22         maxindex = 0
    23         maxval = -1
    24         for i in range(right,left,-1):
    25             cur = height[i]
    26             if cur>maxval:
    27                 maxval=cur
    28                 maxindex = i
    29         waterlevel = min(maxval,leftval)
    30         for i in range(left+1,maxindex):
    31             sums += max(0,waterlevel-height[i])
    32         sums +=self.calRight(height,waterlevel,maxindex,len(height)-1)
    33         return sums
    34 
    35     def trap(self, height: 'List[int]') -> int:
    36         maxindex = 0
    37         maxval = -1
    38         sums = 0
    39         for i in range(len(height)):
    40             curval = height[i]
    41             if curval > maxval:
    42                 maxval = curval
    43                 maxindex = i
    44         sums += self.calLeft(height,maxval,0,maxindex)
    45         sums += self.calRight(height,maxval,maxindex,len(height)-1)
    46         return sums

    这道题的主要思想是搜索,先找到最大的值maxval,对应的索引maxindex,然后向左右两个方向分别搜索。记height的长度为length。

    左侧的部分[0,maxindex),从小到大寻找当前区间的最大值leftmaxval,对应的索引leftmaxindex,然后从计算(leftmax,maxindex)之间的区域。

    用递归的方式,继续计算[0,leftmaxindex),一直到这个区间长度为0,不再进行递归。

    同理,右侧部分(maxindex,length],从大到小寻找最大值rightmaxval,对应的索引rightmaxindex,然后计算(midindex,rightmaxindex)之间的区域。

    用递归的方式,继续计算(rightmaxindex,length],一直到这个区间的长度为0,不再进行递归。

    在主函数中,找到全局的(第一个出现的,也可以是任意一个)最大值,然后分别调用左右两侧的递归方法。

    这里有个小技巧(贪心思想),就是左侧区间找最靠左的最大值,右侧区找最靠右的最大值。这样能尽可能扩大每次搜索所确定的区域,使得在每次搜索到多个相等的最大值时,可以减少递归次数。

    本题还有其他的解决方案,使用非递归的方式效率更高。

  • 相关阅读:
    值得收藏的146条经典民间偏方[转]
    删除暴风文件夹内的stormliv.exe
    【转】VLAN技术浅谈
    [转载]双击.dsw文件时另开VC6.0,而不会关掉原来已打开的项目的解决办法(转载)
    JVM系列1:Java内存区域
    并发系列3:Lock锁以及核心类AQS
    并发系列1:并发基础知识
    JVM系列2:垃圾收集器与内存分配策略
    JVM系列3:类加载机制
    源码解析之AQS源码解析
  • 原文地址:https://www.cnblogs.com/asenyang/p/10475410.html
Copyright © 2011-2022 走看看