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的更多相关文章

  1. [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 ...

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

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  3. [LintCode] Trapping Rain Water 收集雨水

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  4. LeetCode:Container With Most Water,Trapping Rain Water

    Container With Most Water 题目链接 Given n non-negative integers a1, a2, ..., an, where each represents ...

  5. LeetCode - 42. Trapping Rain Water

    42. Trapping Rain Water Problem's Link ------------------------------------------------------------- ...

  6. 有意思的数学题:Trapping Rain Water

    LeetCode传送门 https://leetcode.com/problems/trapping-rain-water/ 目标:找出积木能容纳的水的“面积”,如图中黑色部分是积木,蓝色为可容纳水的 ...

  7. [Leetcode][Python]42: Trapping Rain Water

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 42: Trapping Rain Waterhttps://oj.leetc ...

  8. leetcode#42 Trapping rain water的五种解法详解

    leetcode#42 Trapping rain water 这道题十分有意思,可以用很多方法做出来,每种方法的思想都值得让人细细体会. 42. Trapping Rain WaterGiven n ...

  9. [array] leetcode - 42. Trapping Rain Water - Hard

    leetcode - 42. Trapping Rain Water - Hard descrition Given n non-negative integers representing an e ...

随机推荐

  1. java和c#中String

    java中: c#中: 1.拼接字符串 sql语句中 in() str="'001','002','003'";至于产生string就这样  str1="'001'&qu ...

  2. selenium自动化测试之整合测试报告

    selenium自动化测试之整合测试报告 标签(空格分隔): 整合报告 如下截图我们添加一个文件叫做:latest_report.py文件, import time import os import ...

  3. 外购半成品报SHORT问题(验货客户)

    描述:下图中可以看到外购半成品层物料报SHORT 2.开始检查数据 --针对外购半成品(外购半成品的成品层有BOM数据,外购半成品没有BOM数据) '; --select * from TB_ADDB ...

  4. 关于OPEN_MAX宏undeclared的问题

    最近在看unp时,I/O复用-poll一章的代码使用到了OPEN_MAX.据书中描述,这一宏定义在limits.h头文件中,指代一个进程在任意时刻能打开的最大描述符数目.但在代码编译时遇到了错误,提示 ...

  5. CUDA error 100 & Decoder not initialized

    项目中用cuda解码时候遇到该错误,这是调用cuda相关库中一些so库版本错误造成的.

  6. 文本工具 TextUtils 字符串

    常用方法: isEmpty:判断字符串是否为空值 getTrimmedLength:获取字符串去除头尾空格之后的长度 isDigitsOnly:判断字符串是否全部由数字组成 ellipsize:如果字 ...

  7. unity 3d音效如何设置?,近大远小

    请问怎么将导入的音频文件设置为“3D Sound”?这是我导入的音频文件: 现在3D音效的设置不在导入音效文件的地方,而是在AudioSource的SpatialBlend属性,0表示2D,1表示3D ...

  8. cookie与webStorage区别

  9. 牛客网 Wannafly挑战赛12 删除子串(线性dp)

    题目描述 给你一个长度为n且由a和b组成的字符串,你可以删除其中任意的部分(可以不删),使得删除后的子串“变化”次数小于等于m次且最长. 变化:如果a[i]!=a[i+1]则为一次变化.(且新的字符串 ...

  10. Windows Server RRAS 配置

    在Windows Server上,RRAS 是 Rounting and Remote Access Service 的简称. 通过 RRAS UI 管理器可实现 VPN 和 NAT 的配置. RRA ...