码迷,mamicode.com
首页 > 移动开发 > 详细

Trapping Rain Water

时间:2016-05-29 22:59:45      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:

Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining. 

For example, 
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.

技术分享

The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcos for contributing this image!

和前面一题Container with Most Water是非常类似的题目。但是这题并非找两个边界使其面积最大,而是要求所有雨水的面积,所以还是很大区别的。

有多种解法,一种是基于栈的,另外一种两次扫描,获取每个柱子的左右两边最高的柱子,而每根柱子可以容纳的雨水就是min(max_left,max_right)。这是一次只算一根柱子的做法。栈的做法是每次横向算一个level(或多个level)的存储水量。

两次扫描的代码很好理解,我的实现如下:

class Solution(object):
    def trap(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        
        if not height or len(height) < 3:
            return 0
        n = len(height)
        left = [height[0]]
        right = [height[-1]]
        #一次完成左右最高值的扫描
        for i in xrange(1,n):
            if height[i-1] > left[-1]:
                left.append(height[i-1])
            else:
                left.append(left[-1])
                
            if height[n-i] > right[-1]:
                right.append(height[n-i])
            else:
                right.append(right[-1])
        water = 0
#计算面积
for i in xrange(1,n-1): res = min(left[i],right[~i]) - height[i] if res > 0: water += res return water

上述做法的时间复杂度为O(n),空间复杂度也为O(n),这种做法可以使用双指针使其空间复杂度降为O(1),详见leetcode discuss,我还没看懂。

基于栈的做法,是使用栈计算一个递减序列,对于栈顶元素来说,栈内倒数第二个元素都比其高,一旦当前遍历到的元素比栈顶要高,则可以计算栈顶这个bar为bottom可以存储的横向水量。所有元素都会执行一次入栈。代码如下:

class Solution(object):
    def trap(self, height):
        """
        :type height: List[int]
        :rtype: int
        """
        
        if not height or len(height) < 3:
            return 0
            
        s = []
        water = 0
        maxBotwater = 0
        i = 0
        
        while i < len(height):
            if not s or height[i] <= height[s[-1]]:
                s.append(i)
                i += 1
            else:
                bot = height[s.pop()]
                maxBotwater = 0 if not s else (min(height[s[-1]],height[i]) - bot)*(i-s[-1]-1)
                water += maxBotwater
            
        return water
        

具体解释参考leetcode discuss.这题理解的很不透彻,只需要再看。

 

 

Trapping Rain Water

标签:

原文地址:http://www.cnblogs.com/sherylwang/p/5540649.html

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