Trapping Rain Water LT42

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 Marcos for contributing this image!
Example:
Input: [0,1,0,2,1,0,1,3,2,1,2,1]
Output: 6
1. 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.
Brute force: for each element/bar, find the left boundary and right boundary, the level of the water trapped on this bar is Min(leftBoundary, rightBoundary) - height[i].
start from the bar, scan to the left to get the leftBoundary, scan to the right to get the rightBoundary
Time complexity: O(n2)
Space complexity: O(1)
class Solution {
public int trap(int[] height) {
int area = 0;
for(int i = 0; i < height.length; ++i) {
int leftBoundary = height[i];
for(int j = 0; j <i; ++j) {
leftBoundary = Math.max(leftBoundary, height[j]);
}
int rightBoundary = height[i];
for(int j = i+1; j < height.length; ++j) {
rightBoundary = Math.max(rightBoundary, height[j]);
}
area += Math.min(leftBoundary, rightBoundary) - height[i];
}
return area;
}
}
1.a It is observed that the leftBoundary and rightBoundary has been recomputed multiple times, with dynamic programing, we could compute them once and store the result in the array.
leftBoundary[i]: maximum height starting from left and ending at i, leftBoundary[i] = Math.max(leftBoundary[i-1], height[i])
rightBoundary[j]: maximum height starting from right and ending at j, rightBoundary[j] = Math.max(rightBoundary[j+1], height[j])
Time Complexity: O(n)
Space Complexity: O(n)
public class SolutionLT42 {
private int findMaxHeight(int[] height) {
int result = 0;
for(int i = 0; i < height.length; ++i) {
if(height[i] > height[result]) {
result = i;
}
}
return result;
}
public int trap(int[] height) {
if(height == null || height.length <= 1) return 0;
int highestBar = findMaxHeight(height);
int area = 0;
int leftBoundary = 0;
for(int i = 0; i < highestBar; ++i) {
leftBoundary = Math.max(leftBoundary, height[i]);
area += leftBoundary - height[i];
}
int rightBoundary = 0;
for(int i = height.length - 1; i > highestBar; --i) {
rightBoundary = Math.max(rightBoundary, height[i]);
area += rightBoundary - height[i];
}
return area;
}
public static void main(String[] args) {
SolutionLT42 subject = new SolutionLT42();
int[] testData = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
System.out.println(subject.trap(testData));
}
}
1.4a Instead of doing two passes, we can start from the two ends to find out the boundary on the go with only 1 pass
if leftBounday <= rightBoundary, ++left, if height[left] < leftBoundary, area = leftBoundary - height[left]; otherwise leftBoundary = height[left]
else ++right, if height[right] < rightBoundary, area = rightBoundary - height[right]; otherwise rightBoundary = height[right]
public class SolutionLT42 {
public int trap(int[] height) {
if(height == null || height.length <= 1) return 0;
int area = 0;
int leftBoundary = height[0];
int rightBoundary = height[height.length - 1];
for(int left = 0, right = height.length - 1; left < right;) {
if(leftBoundary <= rightBoundary) {
++left;
leftBoundary = Math.max(leftBoundary, height[left]);
area += leftBoundary - height[left];
}
else {
--right;
rightBoundary = Math.max(rightBoundary, height[right]);
area += rightBoundary - height[right];
}
}
return area;
}
public static void main(String[] args) {
SolutionLT42 subject = new SolutionLT42();
int[] testData = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
System.out.println(subject.trap(testData));
}
}
2. Use stack, in order to store the boundary for a bar, we need to store the index of height in decreasing order of height, hence the previous element before the current would be the leftBoundary, if height[i] <= height[leftBoundaryStack.peek()], leftBoundaryStack.push(i); otherwise, the current element would be the rightBoundary.
public class SolutionLT42 {
public int trap(int[] height) {
if(height == null || height.length <= 1) return 0;
int area = 0;
Deque<Integer> leftBoundaryStack = new LinkedList<>();
for(int i = 0; i < height.length; ++i) {
while(!leftBoundaryStack.isEmpty() && height[leftBoundaryStack.peek()] < height[i]) {
int rightBoundary = height[i];
int current = leftBoundaryStack.pop();
if(leftBoundaryStack.isEmpty()) {
break;
}
int leftBoundary = height[leftBoundaryStack.peek()];
area += (Math.min(leftBoundary, rightBoundary) - height[current]) * (i - leftBoundaryStack.peek() - 1);
}
leftBoundaryStack.push(i);
}
return area;
}
}
Refactoring the above code, replace while loop with if, especially the ++i, interesting...
public class SolutionLT42 {
public int trap(int[] height) {
if(height == null || height.length <= 1) return 0;
int area = 0;
Deque<Integer> leftBoundaryStack = new LinkedList<>();
for(int i = 0; i < height.length;) {
if(leftBoundaryStack.isEmpty() || height[leftBoundaryStack.peek()] > height[i]) {
leftBoundaryStack.push(i);
++i;
}
else {
int current = leftBoundaryStack.pop();
if(leftBoundaryStack.isEmpty()) {
continue;
}
int rightBoundary = height[i];
int leftBoundary = height[leftBoundaryStack.peek()];
int distance = i - leftBoundaryStack.peek() - 1;
int boundedHeight = Math.min(leftBoundary, rightBoundary) - height[current];
area += distance * boundedHeight;
}
}
return area;
}
}
Trapping Rain Water LT42的更多相关文章
- [LeetCode] Trapping Rain Water II 收集雨水之二
Given an m x n matrix of positive integers representing the height of each unit cell in a 2D elevati ...
- [LeetCode] Trapping Rain Water 收集雨水
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- [LintCode] Trapping Rain Water 收集雨水
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- LeetCode:Container With Most Water,Trapping Rain Water
Container With Most Water 题目链接 Given n non-negative integers a1, a2, ..., an, where each represents ...
- LeetCode - 42. Trapping Rain Water
42. Trapping Rain Water Problem's Link ------------------------------------------------------------- ...
- 有意思的数学题:Trapping Rain Water
LeetCode传送门 https://leetcode.com/problems/trapping-rain-water/ 目标:找出积木能容纳的水的“面积”,如图中黑色部分是积木,蓝色为可容纳水的 ...
- [Leetcode][Python]42: Trapping Rain Water
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 42: Trapping Rain Waterhttps://oj.leetc ...
- leetcode#42 Trapping rain water的五种解法详解
leetcode#42 Trapping rain water 这道题十分有意思,可以用很多方法做出来,每种方法的思想都值得让人细细体会. 42. Trapping Rain WaterGiven n ...
- [array] leetcode - 42. Trapping Rain Water - Hard
leetcode - 42. Trapping Rain Water - Hard descrition Given n non-negative integers representing an e ...
随机推荐
- SVN获取最新代码,完成后续开发
1.新建一个文件夹,鼠标右键点击文件夹,点击Checkout 2.填写两个路径(项目路径和下载到路径),并确认“ok”
- 【Scheme】树结构
将表作为序列的表示方式,可以推广到元素本身也是序列的序列.例如,我们可以认为对象((1 2) 3 4)是通过(cons (list 1 2) (list 3 4))构造出来的. 这个表包含三个项,其中 ...
- sqlserver 事务嵌套
参考 https://www.cnblogs.com/JentleWang/p/3654603.html https://blog.csdn.net/tuzhen007/article/details ...
- poj2492(带权并查集)
题目链接:http://poj.org/problem?id=2492 题意:给出n个人,m条关系,每条关系表示的两个人异性,判断这m条关系是否有误. 思路:带权并查集,类似poj1182,并查集的向 ...
- 思维+并查集 hdu5652
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5652 题意: 输入T,接下来T个样例,每个样例输入n,m代表图的大小,接下来n行,每行m个数,代表图, ...
- 学习Auxre记录
1.下载地址:https://www.axure.com.cn/3510/(可以免费试用30天) 2.视频教程:https://huke88.com/course/6455.html 3.文字教程:h ...
- P3375 【模板】KMP字符串匹配
P3375 [模板]KMP字符串匹配 https://www.luogu.org/problemnew/show/P3375 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在 ...
- [剑指Offer]25-合并两个排序链表
题目链接 https://www.nowcoder.com/practice/d8b6b4358f774294a89de2a6ac4d9337?tpId=13&tqId=11169&t ...
- Hashed collections哈希集合
[定义] 有index的集合 [hash的原理] term for a situation when two different objects return the same hashcode: h ...
- AngularJS——第6章 作用域
第6章 作用域 在AngularJS中使用过滤器格式化展示数据,在"{{}}"中使用"|"来调用过滤器,使用":"传递参数. 6.1 内置过 ...