[leetcode] 407. Trapping Rain Water II 解题报告

来源:互联网 发布:常用排序算法 编辑:程序博客网 时间:2024/05/27 09:45

题目链接:https://leetcode.com/problems/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.

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 are trapped between the blocks. The total volume of water trapped is 4


思路:如果做过这题I的应该知道,在第一题中基本思路是每次从两端的高度较小的一端移动,这样做的意义在于我们每次都是遍历最短的一个位置,也就是根据木桶原理这里最可能漏水,还需要维护一个当前边界的最大值.这样如果如果某一个高度小于当前维护的边界最大值,那么这里就可以保存一些水.

二维的原理和一维的思路基本是一样的.在一维中我们只需从两个端点选一个即可,而在二维中可选的点就扩大成了整个矩形的边.根据上一题知道我们同样每次应该先选取边界最小的高度,所以很自然的可以想到应该用优先队列来保存周围边界(小顶堆).在我们访问过了一个点之后要继续往矩形内部遍历,这样还需要保存一个点的位置.为了防止再次访问已经访问过的点还需要用一个数组来标记每个点的访问状态.

时间复杂度应该是O(m*n*log(m+n)).

代码如下:

class Solution {public:    int trapRainWater(vector<vector<int>>& heightMap) {        if(heightMap.size()==0) return 0;        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> que;        int row = heightMap.size(), col = heightMap[0].size();        vector<vector<int>> visited(row, vector<int>(col, 0));        int ans = 0, Max = INT_MIN;        for(int i = 0; i < row; i++)        {            for(int j = 0; j < col; j++)            {                if(!(i==0 || i==row-1 || j==0 || j==col-1)) continue;                que.push(make_pair(heightMap[i][j], i*col+j));                visited[i][j] = 1;            }        }        vector<vector<int>> dir{{1, 0}, {-1, 0}, {0, 1}, {0, -1}};        while(!que.empty())        {            auto val = que.top(); que.pop();            int height = val.first, x = val.second/col, y = val.second%col;            Max = max(Max, height);            for(auto d: dir)            {                int x2 = x + d[0], y2 = y + d[1];                if(x2>=row || x2<0 || y2<0 || y2>=col || visited[x2][y2]) continue;                visited[x2][y2] = 1;                if(heightMap[x2][y2] < Max) ans += Max - heightMap[x2][y2];                que.push(make_pair(heightMap[x2][y2], x2*col+y2));            }        }        return ans;    }};


1 1
原创粉丝点击