42. Trapping Rain Water 及类似题目 407. Trapping Rain Water II 11. Container With Most Water
来源:互联网 发布:儿童医院在线咨询网络 编辑:程序博客网 时间:2024/05/28 18:44
42. Trapping Rain Water
Given n non-negative integers representing an elevation map where the width of each bar is 1, compute how much water it is able to trap after raining.
For example,
Given [0,1,0,2,1,0,1,3,2,1,2,1]
, return 6
.
The above elevation map is represented by array [0,1,0,2,1,0,1,3,2,1,2,1]. In this case, 6 units of rain water (blue section) are being trapped. Thanks Marcosfor contributing this image!
思路1:对每个台阶都寻找左右最大的围墙对于每一个台阶,都向左和向右寻找最高的那个墙壁,那么最终这个台阶的需水量等于min(maxRight,maxLeft)-height[i]代码如下:
时间复杂度是O(n2)
int trap(vector<int>& height){ int ans = 0; int size = height.size(); for (int i = 1; i < size - 1; i++) { int max_left = 0, max_right = 0; for (int j = i; j >= 0; j--) { //Search the left part for max bar size max_left = max(max_left, height[j]); } for (int j = i; j < size; j++) { //Search the right part for max bar size max_right = max(max_right, height[j]); } ans += min(max_left, max_right) - height[i]; } return ans;}
思路2:动态规划方法,建立左右墙壁两个数组
上图的意思是:
分两步考虑,对于一个台阶,只看他左边的最高墙壁,认为右边墙壁和左边墙壁相等,这样每个台阶的储水量都可以求得。而且,左边最高墙壁可以在一次遍历过程中不断更新(只有当前墙壁高于之前的最高墙壁才会更新);
同样的道理,可以得到只考虑右边墙壁时得到的各台阶的需水量。
一个台阶的实际需水量等于上面两个数组相应位置的最小值。
实际左右分开遍历矩阵时,只需要保存最高墙壁。最后一次遍历时再求需水量
int trap(vector<int>& height){ if(height == null) return 0; int ans = 0; int size = height.size(); vector<int> left_max(size), right_max(size); left_max[0] = height[0]; for (int i = 1; i < size; i++) {//从左至右遍历,保存当前台阶的左边最大墙壁 left_max[i] = max(height[i], left_max[i - 1]); } right_max[size - 1] = height[size - 1]; for (int i = size - 2; i >= 0; i--) {//从右至左遍历,保存当前台阶的左边最大墙壁 right_max[i] = max(height[i], right_max[i + 1]); } for (int i = 1; i < size - 1; i++) {//左右墙壁的最小值-当前台阶的高度是当前台阶的需水量 ans += min(left_max[i], right_max[i]) - height[i]; } return ans;}思路3:使用栈 时间复杂度O(n),空间复杂度O(n)
可以在一次遍历求得最大需水量
栈为空时,先进栈。
栈不为空时:如果栈顶元素高度大于等于当前高度current,进栈;如果栈顶元素小于当前高度,出栈,计算出栈的元素的蓄水量,找到现在的栈顶和current的最小高度,乘以两个墙壁的距离得到蓄水量,这个蓄水量是栈顶元素做墙的蓄水量。然后继续比较current和栈顶,如果还是满足current>栈顶,继续重复上述操作。这种蓄水方式实际上是一层一层的注水。(这个可以实现的原因是,栈顶的下面的高度一定大于等于上面的值)
当前蓄水完成之后(这些节点的蓄水量一定是全部加完的),再将current进栈,重复外层循环。
int trap(vector<int>& height){ int ans = 0, current = 0; stack<int> st; while (current < height.size()) { while (!st.empty() && height[current] > height[st.top()]) { int top = st.top(); st.pop(); if (st.empty()) break; int distance = current - st.top() - 1; int bounded_height = min(height[current], height[st.top()]) - height[top]; ans += distance * bounded_height; } st.push(current++); } return ans;}
思路4:使用双指针
这个方法较难想到:
left。right分别在两端,分别保存左右最大值,如果左墙壁最大值小于右墙壁最大值,那么左指针当前台阶的蓄水量由左墙壁决定,这个时候更新左墙壁(因为下一个左墙壁可能还小与右墙壁)。
相反,如果左墙壁最大值大于等于右墙壁最大值,那么右指针当前台阶的蓄水量由右墙壁决定,这个时候更新右墙壁(因为下一个右墙壁可能还小与左墙壁)。
Time complexity: O(n)O(n). Single iteration of O(n)O(n).
Space complexity: O(1)O(1) extra space. Only constant space required for \text{left}left, \text{right}right, left_maxleft_max and right_maxright_max.
int trap(vector<int>& height){ int left = 0, right = height.size() - 1; int ans = 0; int left_max = 0, right_max = 0; while (left < right) { if (height[left] < height[right]) { height[left] >= left_max ? (left_max = height[left]) : ans += (left_max - height[left]); ++left; } else { height[right] >= right_max ? (right_max = height[right]) : ans += (right_max - height[right]); --right; } } return ans;}
11. Container With Most Water
Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container and n is at least 2.
寻找两条线,他们围成得水池蓄水最多
两个指针分别从左和右向中间逼近。每次计算水池大小(与全局变量比较)。向中间逼近时,只有遇到更高得柱子,才考虑更新水池大小。
class Solution {public: int maxArea(vector<int>& height) { int n=height.size(); int areamax=0; int i=0,j=n-1; while(i<j) { int hmin=min(height[i],height[j]); areamax=max(areamax,(j-i)*hmin); while(height[i]<=hmin&&i<j) { ++i; } while(height[j]<=hmin&&i<j) { j--; } } return areamax; }};
Leetcode 407. Trapping Rain Water II 收集雨水2 解题报告 使用优先级队列,用pair<int,int> 将矩阵坐标转换成一维值
class Solution {public: int trapRainWater(vector<vector<int>>& heightMap) { typedef pair<int,int> cell; priority_queue<cell, vector<cell>, greater<cell>> q; int m = heightMap.size(); if (m == 0) return 0; int n = heightMap[0].size(); vector<int> visited(m*n, false); 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) { if (!visited[i*n+j]) q.push(cell(heightMap[i][j], i*n+j)); visited[i*n+j] = true; } } int dir[4][2] = {{0,1}, {0, -1}, {1, 0}, {-1, 0}}; int ans = 0; while(!q.empty()) { cell c = q.top(); q.pop(); int i = c.second/n, j = c.second%n; for (int r = 0; r < 4; ++r) { int ii = i+dir[r][0], jj = j+dir[r][1]; if (ii < 0 || ii >= m || jj < 0 || jj >= n || visited[ii*n+jj]) continue; ans += max(0, c.first - heightMap[ii][jj]); q.push(cell(max(c.first, heightMap[ii][jj]), ii*n+jj)); visited[ii*n+jj] = true; } } return ans; }};
阅读全文
0 0
- 42. Trapping Rain Water 及类似题目 407. Trapping Rain Water II 11. Container With Most Water
- [LeetCode]Container With Most Water、Trapping Rain Water
- leetcode之Container With Most Water 和Trapping Rain Water
- Trapping Rain Water II
- Trapping Rain Water II
- Trapping Rain Water II
- Trapping Rain Water II
- 407. Trapping Rain Water II
- 407. Trapping Rain Water II
- 407. Trapping Rain Water II
- 407. Trapping Rain Water II
- 407. Trapping Rain Water II
- 407. Trapping Rain Water II
- 42.Trapping Rain Water
- 42. Trapping Rain Water
- 42. Trapping Rain Water
- 42. Trapping Rain Water
- 42. Trapping Rain Water
- redis的自启设置
- DFS(深度搜索)——基于回溯法和递归
- Unity学习2 鼠标点击控制物体移动
- C++语法基础之关键字与标识符(10月4日暂存)
- 295. Find Median from Data Stream 剑指offer 数据流中的中位数
- 42. Trapping Rain Water 及类似题目 407. Trapping Rain Water II 11. Container With Most Water
- linux内核--资源管理
- 162. Find Peak Element 一次遍历或二分查找
- 【python】100行代码python爬虫程序,抓取网站图片存储本地(附:中文链接解决)
- curl windows下编译lib
- jenkins加docker自动化部署
- 输出四位数各位上的数字
- 使用 IDEA 整合 SSH 发生 Mapping (RESOURCE) not found 错误
- java面试题