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. express 中间件

    [express 中间件] 中间件(Middleware) 是一个函数,它可以访问请求对象(request object (req)), 响应对象(response object (res)), 和 ...

  2. native和webview切换

    native和webview 标签(空格分隔): native和webview 现在目前大部分的app都是native和webview混合,对应的native上的元素可以通过uiautomatorvi ...

  3. IN_ORDER_PLANNING、IN_BOM_CHANGE

    一.IN_ORDER_PLANNING 新增一个IN表(IN_ORDER_PLANNING,把ZFP037和ZFP026整合成一张表,标示哪些订单的是真验货/假验货.VIP真验货/假验货订单) ORD ...

  4. Integer 原码解读

    有一天,突然发现,阅读原码可以发现很多有趣的东西.在Java中,我们知道很多东西都是封装好的,拿来即用,当你有一天去研究它拿来的东西是如何具体操作的,将会是非常有趣的事情. 在上一篇研究HashMap ...

  5. 截图软件FastStone

    屏幕截图软件(FastStone Capture) 好用,可以粘贴 / 复制. 可以做页面设计,有屏幕标尺,取色器.

  6. 分布式处理框架MapReduce的深入简出

    1).MapReduce的概述 2).MapReduce 编程模型 3).MapReduce架构 4).MapReduce编程 Google MapReduce论文,论文发表于2004年 Hadoop ...

  7. 189. Rotate Array(Array)

    Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array ...

  8. http://ctf.bugku.com/challenges#Easy_Re

      今天做一道逆向题,开心,见证了自己汇编的用途.     首先看它是否加壳? 1.加壳检测   是vc编程的,没有加壳,可以愉快地分析了.   2.分析程序,找到flag.   首先运行一下子程序, ...

  9. Linux 有线 校园网

    1.首先在ifconfig命令在终端查看自己的ip地址,然后记录下来 2.然后用sudo -i 命令转换到root权限下 3.在自己家目录下输入pppoeconf 4.遇到username时,讲自己的 ...

  10. 【校招面试 之 C/C++】第33题 C++ 11新特性(四)之STL容器

    C++ 11新增array.forward_list(单链表).unordered_set.unordered_map集中容器.