LeetCode 407. Trapping Rain Water II

简介: 我们把最外面的四边当成四面墙,想象海水面不断的升高,首先会浸过墙面最低的格子,如果墙面最低格子的四周(出了在墙面的格子)有比它矮的格子,那么这就可以形成一个蓄水池,蓄水池的最高高度就是墙面最低的格子,于是我们计算这个蓄水池可以获得的蓄水量;然后这个蓄水池被添加到墙面中;继续在墙面中找最低的格子;

v2-595b41a793219676dba696199a1229dc_1440w.jpg

Description



Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevation map, compute the volume of water it is able to trap after raining.


Note:

Both m and n are less than 110. The height of each unit cell is greater than 0 and is less than 20,000.


Example:

Given the following 3x6 height map:

[

[1,4,3,1,3,2],

[3,2,1,3,2,4],

[2,3,3,2,3,1]

]

Return 4.


The above image represents the elevation map [[1,4,3,1,3,2],[3,2,1,3,2,4],[2,3,3,2,3,1]] before the rain.

After the rain, water is trapped between the blocks. The total volume of water trapped is 4.


思路


  • 这道题虽然叫 Trapping Rain Water II,但是题目的解法和 Trapping Rain Water 并不一样。
  • 这道题用到的基本数据结构是小顶堆。
  • 基本思路是:我们想象海平面的海水慢慢侵入方格,依次找到会被海水填满的格子。
  • 我们把最外面的四边当成四面墙,想象海水面不断的升高,首先会浸过墙面最低的格子,如果墙面最低格子的四周(出了在墙面的格子)有比它矮的格子,那么这就可以形成一个蓄水池,蓄水池的最高高度就是墙面最低的格子,于是我们计算这个蓄水池可以获得的蓄水量;然后这个蓄水池被添加到墙面中;继续在墙面中找最低的格子;
  • 这个视频的动画解释的非常清楚


# -*- coding: utf-8 -*-
# @Author:             何睿
# @Create Date:        2019-10-03 08:11:17
# @Last Modified by:   何睿
# @Last Modified time: 2019-10-03 11:57:48
import heapq
from typing import List
class Solution:
    def trapRainWater(self, heightMap: List[List[int]]) -> int:
        if not heightMap or not heightMap[0]:
            return 0
        queue, visited, max_heigth, water = [], set(), 0, 0
        row, col = len(heightMap), len(heightMap[0])
        count = row * col
        self.fill_border(queue, heightMap)
        visited = {(row, col) for _, row, col in queue}
        while queue:
            # 当所有的格子都在墙面上时,结束
            if len(visited) == count:
                return water
            height, i, j = heapq.heappop(queue)
            max_heigth = max(max_heigth, height)
            # 以最低的格子为起点,判断四周是否可以形成蓄水池,返回蓄水池蓄水的大小
            water += self.visit_neighbors(queue, visited, heightMap, max_heigth, row, col, i, j)
        return water
    def visit_neighbors(self, queue, visited, heightMap, max_heigth, row, col, i, j):
        water = 0
        for x, y in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
            nrow, ncol = i + x, j + y
            if (nrow, ncol) not in visited and self.is_in_border(row, col, nrow, ncol):
                num = heightMap[nrow][ncol]
                water += max(0, max_heigth - num)
                visited.add((nrow, ncol))
                heapq.heappush(queue, (num, nrow, ncol))
        return water
    def fill_border(self, queue, heightMap):
        row, col = len(heightMap), len(heightMap[0])
        for i in range(row):
            heapq.heappush(queue, (heightMap[i][0], i, 0))
            heapq.heappush(queue, (heightMap[i][-1], i, col - 1))
        for i in range(1, col - 1):
            heapq.heappush(queue, (heightMap[0][i], 0, i))
            heapq.heappush(queue, (heightMap[-1][i], row - 1, i))
    def is_in_border(self, row, col, i, j):
        return 0 <= i < row and 0 <= j < col


源代码文件在 这里


目录
相关文章
|
人工智能 容器
Leetcode 11. Container With Most Water
题目可以这么理解,在i位置有条高为ai的竖线,让你选出两台竖线构成一个容器,使得该容器装的水最多,注意容器不能倾斜。
47 3
Leetcode 365. Water and Jug Problem
一句话理解题意:有容积为x和y升的俩水壶,能不能量出z升的水。 我刚开始看到这题,立马就想了下暴力搜索的可能性,但考虑了下数据大小,立马放弃这个暴力的想法,于是意识到肯定有比较简单的数学方法,其实我自己没想到,后来看还是看了别人的代码,很多博客都直接给出了解法, 但没介绍为什么能这么解。所以我决定解释下我自己的思路。
48 0
LeetCode 417. Pacific Atlantic Water Flow
给定一个 m x n 的非负整数矩阵来表示一片大陆上各个单元格的高度。“太平洋”处于大陆的左边界和上边界,而“大西洋”处于大陆的右边界和下边界。 规定水流只能按照上、下、左、右四个方向流动,且只能从高到低或者在同等高度上流动。 请找出那些水流既可以流动到“太平洋”,又能流动到“大西洋”的陆地单元的坐标。
109 0
LeetCode 417. Pacific Atlantic Water Flow
|
索引
LeetCode 42 Trapping Rain Water
给定n个非负整数,每个非负整数表示一个宽度为1的柱子,计算下雨后能够捕获多少水.
70 0
LeetCode 42 Trapping Rain Water
|
机器学习/深度学习 PHP 索引
[Leetcode 之 PHP 解析 (42. Trapping Rain Water)
[Leetcode 之 PHP 解析 (42. Trapping Rain Water)
106 0
[Leetcode 之 PHP 解析 (42. Trapping Rain Water)
|
容器
Leetcode-Medium 11. Container With Most Water
Leetcode-Medium 11. Container With Most Water
98 0
Leetcode-Medium 11. Container With Most Water
LeetCode - 42. Trapping Rain Water
42. Trapping Rain Water  Problem's Link  ---------------------------------------------------------------------------- Mean:  在坐标上给你一些竖直放置的条形积木,问你这个积木能够容纳多少液体.
898 0
|
容器
LeetCode - 11. Container With Most Water
11. Container With Most Water  Problem's Link  ---------------------------------------------------------------------------- Mean:...
1009 0
|
2月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
3月前
|
搜索推荐 索引 Python
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
113 2