364. 接雨水 II

Posted yunxintryyoubest

tags:

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

364. 接雨水 II

中文English

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

技术图片

样例

样例 1:

例如,给定一个 5*4 的矩阵: 
输入:
[[12,13,0,12],[13,4,13,12],[13,8,10,12],[12,13,12,12],[13,13,13,13]]
输出:
14

样例 2:

输入:
[[2,2,2,2],[2,2,3,4],[3,3,3,1],[2,3,4,5]]
输出:
0
 
 
输入测试数据 (每行一个参数)如何理解测试数据?

 堆(最小堆) + 木桶原理(边界最小高度切入,由外及内) 

边界最小的高度决定了里面存储的水量,当然内层如果存在高度更大的边界,存储的水量更多

import  heapq 
class Solution:
    """
    @param heights: a matrix of integers
    @return: an integer
    """
    def __init__(self):
        self.borders = []
        self.visited = set()
    
    def trapRainWater(self, heights):
        # write your code here
        #木桶原理,边界最小高度木板决定了里面的水量,由外向内遍历
        #切入点,边界最小高度往里面切入
        ‘‘‘
        需要:
        self.visited = set() 已经访问过的不需要再进行访问,只需要x,y即可
        heapq borders 堆里面存储的是所有的边界,包括x,y,height 
        total 总水量
        len_y, len_x 初始y轴和x轴长度
        
        ‘‘‘
        if not heights: return 0 

        def adjust(x, y):
            new_array = []
            direction = [[0, 1], [0, -1], [1, 0], [-1, 0]]
            for d in direction:
                new_x = x + d[0]
                new_y = y + d[1]
            
                if (0 <= new_x < self.len_y) and (0 <= new_y < self.len_x) and (new_x, new_y) not in self.visited:
                    new_array.append((new_x, new_y))
                    
            return new_array
    
        #初始化
        def initialize(heights):
            #找到所有的边界,x轴分别为0,len_x - 1 
            for i in range(self.len_y):
                add(i, 0, heights[i][0])
                add(i, self.len_x - 1, heights[i][self.len_x - 1])
                
            for j in range(self.len_x):
                add(0, j, heights[0][j])
                add(self.len_y - 1, j, heights[self.len_y - 1][j])
                              
        
        def add(x, y, height):
            heapq.heappush(self.borders, [height, x, y])
            self.visited.add((x, y))
        
        total = 0 
        self.len_x, self.len_y = len(heights[0]), len(heights)
        
        initialize(heights)
        
        #从边界切入,每次去堆里面取最小值出来
        while self.borders:
            cell_height, x, y = heapq.heappop(self.borders)
            
            #然后在当前切入的边界最小高度上下左右的找,如果小于,则存储水,否则0
            for new_x, new_y in adjust(x, y):
                total += max(cell_height - heights[new_x][new_y], 0)
                #细节,后面height加的是内层的最大高度,因为最外层已经确定了所有高度,切入点也是从最外层最小高度开始切入的,内层的高度不影响了最外层高度,只能是比最外层最大高度高来影响里面
                add(new_x, new_y, max(cell_height, heights[new_x][new_y]))
        
        return total
            

        
        

 

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

407. 接雨水 II (优先队列)

2021-07-15:接雨水 II。给你一个 m x n 的矩阵,其中的值均为非负整数,代表二维高度图每个单元的高度,请计算图中形状最多能接多少体积的雨水。

LeetCode 407 接雨水 II[最小堆] HERODING的LeetCode之路

LeetCode 575. 分糖果 / 237. 删除链表中的节点 / 407. 接雨水 II

最强解析面试题:接雨水...

java刷题--42接雨水