zoukankan      html  css  js  c++  java
  • [LeetCode] 407. Trapping Rain Water II 收集雨水 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.

    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.

    42. Trapping Rain Water的拓展,由2D变3D了。解法跟之前的完全不同了,之前那道题由于是二维的,我们可以用双指针来做,而这道三维的,我们需要用BFS来做。

    Java: Priority Queue

    public class Solution {
    
        public class Cell {
            int row;
            int col;
            int height;
            public Cell(int row, int col, int height) {
                this.row = row;
                this.col = col;
                this.height = height;
            }
        }
    
        public int trapRainWater(int[][] heights) {
            if (heights == null || heights.length == 0 || heights[0].length == 0)
                return 0;
    
            PriorityQueue<Cell> queue = new PriorityQueue<>(1, new Comparator<Cell>(){
                public int compare(Cell a, Cell b) {
                    return a.height - b.height;
                }
            });
            
            int m = heights.length;
            int n = heights[0].length;
            boolean[][] visited = new boolean[m][n];
    
            // Initially, add all the Cells which are on borders to the queue.
            for (int i = 0; i < m; i++) {
                visited[i][0] = true;
                visited[i][n - 1] = true;
                queue.offer(new Cell(i, 0, heights[i][0]));
                queue.offer(new Cell(i, n - 1, heights[i][n - 1]));
            }
    
            for (int i = 0; i < n; i++) {
                visited[0][i] = true;
                visited[m - 1][i] = true;
                queue.offer(new Cell(0, i, heights[0][i]));
                queue.offer(new Cell(m - 1, i, heights[m - 1][i]));
            }
    
            // from the borders, pick the shortest cell visited and check its neighbors:
            // if the neighbor is shorter, collect the water it can trap and update its height as its height plus the water trapped
           // add all its neighbors to the queue.
            int[][] dirs = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
            int res = 0;
            while (!queue.isEmpty()) {
                Cell cell = queue.poll();
                for (int[] dir : dirs) {
                    int row = cell.row + dir[0];
                    int col = cell.col + dir[1];
                    if (row >= 0 && row < m && col >= 0 && col < n && !visited[row][col]) {
                        visited[row][col] = true;
                        res += Math.max(0, cell.height - heights[row][col]);
                        queue.offer(new Cell(row, col, Math.max(heights[row][col], cell.height)));
                    }
                }
            }
            
            return res;
        }
    }  

    Python:

    from heapq import heappush, heappop
    
    class Solution(object):
        def trapRainWater(self, heightMap):
            """
            :type heightMap: List[List[int]]
            :rtype: int
            """
            m = len(heightMap)
            if not m:
                return 0
            n = len(heightMap[0])
            if not n:
                return 0
    
            is_visited = [[False for i in xrange(n)] for j in xrange(m)]
    
            heap = []
            for i in xrange(m):
                heappush(heap, [heightMap[i][0], i, 0])
                is_visited[i][0] = True
                heappush(heap, [heightMap[i][n-1], i, n-1])
                is_visited[i][n-1] = True
            for j in xrange(n):
                heappush(heap, [heightMap[0][j], 0, j])
                is_visited[0][j] = True
                heappush(heap, [heightMap[m-1][j], m-1, j])
                is_visited[m-1][j] = True
    
            trap = 0
            while heap:
                height, i, j = heappop(heap)
                for (dx, dy) in [(1,0), (-1,0), (0,1), (0,-1)]:
                    x, y = i+dx, j+dy
                    if 0 <= x < m and 0 <= y < n and not is_visited[x][y]:
                        trap += max(0, height - heightMap[x][y])
                        heappush(heap, [max(height, heightMap[x][y]), x, y])
                        is_visited[x][y] = True
    
            return trap  

    C++:

    class Solution {
    public:
        int trapRainWater(vector<vector<int>>& heightMap) {
            if (heightMap.empty()) return 0;
            int m = heightMap.size(), n = heightMap[0].size(), res = 0, mx = INT_MIN;
            priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
            vector<vector<bool>> visited(m, vector<bool>(n, false));
            vector<vector<int>> dir{{0,-1},{-1,0},{0,1},{1,0}};
            for (int i = 0; i < m; ++i) {
                for (int j = 0; j < n; ++j) {
                    if (i == 0 || i == m - 1 || j == 0 || j == n - 1) {
                        q.push({heightMap[i][j], i * n + j});
                        visited[i][j] = true;
                    }
                }
            }
            while (!q.empty()) {
                auto t = q.top(); q.pop();
                int h = t.first, r = t.second / n, c = t.second % n;
                mx = max(mx, h);
                for (int i = 0; i < dir.size(); ++i) {
                    int x = r + dir[i][0], y = c + dir[i][1];
                    if (x < 0 || x >= m || y < 0 || y >= n || visited[x][y]) continue;
                    visited[x][y] = true;
                    if (heightMap[x][y] < mx) res += mx - heightMap[x][y];
                    q.push({heightMap[x][y], x * n + y});
                }
            }
            return res;
        }
    };
    

     

    类似题目:

    [LeetCode] 42. Trapping Rain Water 收集雨水

    All LeetCode Questions List 题目汇总

     

  • 相关阅读:
    使用正则表达式,取得点击次数,函数抽离
    爬取校园新闻首页的新闻
    网络爬虫基础练习
    Hadoop大作业
    Hive基本操作与应用
    熟悉HBase基本操作
    爬虫大作业
    熟悉常用的HDFS操作
    数据结构化与保存
    使用正则表达式,取得点击次数,函数抽离
  • 原文地址:https://www.cnblogs.com/lightwindy/p/8532201.html
Copyright © 2011-2022 走看看