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 ...
随机推荐
- cakePHP的ajax弹出窗
在html里添加一个触发弹出框的按钮 $("#button1").on("click", function() { $("#dialogue" ...
- vue 学习1
.static{ border-radius:4px; } .active { width: 100px; height: 100px; background: green; } .text-dang ...
- 打印信息,通过.jasper工具将集合输出到PDF文件 然后利用打印机打印文件
我们上一次成功的利用iReport工具制作了一张报表,并且预览了报表最后的效果,也生成了格式为“jrpxml”.“jrxml”与“jasper”的文件.这次,我们使用jasper提供的java的api ...
- 将tomcat做成windows服务
@参考文章 大致步骤: 1,配置环境变量(选读) 2,安装 3,卸载(选读) 配置环境变量: 这块不是必须的.我不喜欢给tomcat配置环境变量,默认即可.如需要配置可看参考文章,也可参考我之前的文章 ...
- swift - 16进制颜色扩展(1.支持# 2.支持不带# , 3支持带0X)
/** * 设置16进制颜色: * 可识别类型 * 1:有# * 2:没有# * 3:含有0X */ extension UIColor{ class func hexadecimalColor(he ...
- swift4.2 - 距离传感器
import UIKit class ViewController: UIViewController { deinit { NotificationCenter.default.removeObse ...
- Tomcat登陆mysql的密码设置
在登陆mysql的密码和数据库密码不一致时,可以修改Mysql数据库密码或者修改连接Mysql的配置文件: 1.修改连接Tomcat里连接Mysql的配置文件 需要修改两个配置文件 ,一个是在tom ...
- js第三天知识点 循环
/*for(重点) *while *do..while * *3种循环的区别: *for 主要适用于 明确循环次数的 循环 *while 适用于 不明确循环次数的循环 *do..while 适用于 ...
- (九)ROS安装rviz模拟器
一 . 什么是 rviz rviz : The ROS Visualization Tool ,即机器人操作系统3D可视化工具.它的作用就是:一个虚拟世界,用来模拟机器人在现实世界的运行效果. 简单的 ...
- pthreads v3下一些坑和需要注意的地方
一.子线程无法访问父线程的全局变量,但父线程可以访问子线程的变量 <?php class Task extends Thread { public $data; public function ...