zoukankan      html  css  js  c++  java
  • [LeetCode] 407. Trapping Rain Water II

    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.

    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.

    接雨水II。给你一个 m x n 的矩阵,其中的值均为非负整数,代表二维高度图每个单元的高度,请计算图中形状最多能接多少体积的雨水。题意跟版本一很像,但是这个题改成三维的了。思路是BFS + priority queue,同时需要一个跟input数组一样大的二维数组visited,记录每个坐标是否被遍历过。里面细节很多,具体讲一讲。

    因为这个题是立体的,所以首先发现的是二维数组的最外面一圈的数字是只能当做墙壁不能盛水的。所以此时将他们加入pq,加入的时候存(横坐标x,纵坐标y,坐标值height)。pq是按坐标值height排序的一个最小堆,意思是坐标值height最小的元素会优先被pop出来。pop出来的时候,扫描这个坐标的四个方向上的没有被visited过的坐标,看他们之间的高度差是否有可能大于0。换言之,每次弹出来的坐标,你把他当做一堵墙,看他是否能为他自己的四个邻居坐标盛水。盛水的原则就是当前坐标的高度cell[2]比他的邻居坐标的高度heightMap[x][y]要高。这个跟版本一很像,无非是版本一只是看左右两个方向,这个题这里是看四个方向。在看四个方向的时候,记得跳过已经访问过的坐标和超出矩阵范围外的坐标。其余的部分就是BFS的套路了。

    时间O(m * n * log(m + n)) - 有两个for loop所以起码是mn,同时pq一开始加入了2m + 2n个元素,每次都是2m + 2n个元素及其四维的元素之间找最小值

    空间O(mn)

    Java实现

     1 class Solution {
     2     public int trapRainWater(int[][] heightMap) {
     3         // corner case
     4         if (heightMap == null || heightMap.length <= 1 || heightMap[0].length <= 1) {
     5             return 0;
     6         }
     7 
     8         // normal case
     9         int m = heightMap.length;
    10         int n = heightMap[0].length;
    11         boolean[][] visited = new boolean[m][n];
    12         PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[2] - b[2]);
    13         for (int i = 0; i < m; i++) {
    14             for (int j = 0; j < n; j++) {
    15                 if (i == 0 || j == 0 || i == m - 1 || j == n - 1) {
    16                     visited[i][j] = true;
    17                     pq.offer(new int[] { i, j, heightMap[i][j] });
    18                 }
    19             }
    20         }
    21 
    22         int res = 0;
    23         int[][] dirs = new int[][] { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 } };
    24         while (!pq.isEmpty()) {
    25             int[] cell = pq.poll();
    26             for (int[] dir : dirs) {
    27                 int x = cell[0] + dir[0];
    28                 int y = cell[1] + dir[1];
    29                 if (x >= 0 && x < m && y >= 0 && y < n && !visited[x][y]) {
    30                     visited[x][y] = true;
    31                     res += Math.max(0, cell[2] - heightMap[x][y]);
    32                     pq.offer(new int[] { x, y, Math.max(cell[2], heightMap[x][y]) });
    33                 }
    34             }
    35         }
    36         return res;
    37     }
    38 }

    flood fill题型总结

    LeetCode 题目总结

  • 相关阅读:
    android 底部菜单栏实现(转)
    android 用webView作为编辑器 各种问题
    android 自定图库(转)
    js document.queryCommandState() 各个参数
    自定义简单的按钮点击动画效果
    android 类似QQ底部输入框弹出键盘和面板冲突 布局闪动处理方案(转)
    android 自定义控件View在Activity中使用findByViewId得到结果为null
    Tinker 热修复框架 简单上手教程
    网页天气模块,包括当天天气和未来四天预报
    关于闭包(closure)的一些概念
  • 原文地址:https://www.cnblogs.com/cnoodle/p/12820604.html
Copyright © 2011-2022 走看看