Trapping Water

Question quoted from lintcode

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.


pic

Example
Given [0,1,0,2,1,0,1,3,2,1,2,1], return 6.

Idea

This question seems easy but indeed tough. You can manually do it intuitively but hardly in code. This is because with a human eye you can easily see the higher bars from left to right until the end. And you will do it by filling water from left, and you will make sure the water level does not exceed the leftmost-high bar and rightmost-high bar.

But why do you know which bar is the leftmost-high and which bar is the rightmost-high given a segment? I spent pretty much time trying to understand how my brain works.

Eventually, I didn't figure it out. But I found a way to let the computer do this.

Steps

  • stepping from left, mark the largest height that is ever seen before this element
  • stepping from right, mark the largest height that is ever seen before this element
  • The water level is the minimum amongst the left boundary bar and right boundary bar. If the element height does not exceed the water level, then we can fill the water.

步驟

  • 從左到右掃描一遍,記錄下當下元素之前遇到的最高值。此爲當下元素的左邊界
  • 從右到左掃描一遍,記錄下當下元素之前遇到的最高值。此爲當下元素的右邊界。
  • 從頭到尾掃描一遍,水平面是當下元素之左右邊界的較小值。若水平面比當下元素高,則可以加水。

Solution

public class Solution {
    /**
     * @param heights: an array of integers
     * @return: a integer
     */
    public int trapRainWater(int[] heights) {
        if (heights.length == 0) return 0;
        
        
        int[] leftMax = new int[heights.length];
        leftMax[0] = 0;
        for(int i = 1; i < heights.length; i++) {
            leftMax[i] = Math.max(leftMax[i - 1], heights[i - 1]);
        }
        
        int[] rightMax = new int[heights.length];
        rightMax[heights.length - 1] = 0;
        for(int i = heights.length - 2; i >= 0; i--) {
            rightMax[i] = Math.max(rightMax[i + 1], heights[i + 1]);
        }

        int water = 0;
        for(int i = heights.length - 1; i >= 0; i--) {
            int waterLevel = Math.min(leftMax[i], rightMax[i]);
            if (waterLevel > heights[i]) {
                water += waterLevel - heights[i];
            }
        }
        return water;
    }
    
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi阅读 7,974评论 0 10
  • **2014真题Directions:Read the following text. Choose the be...
    又是夜半惊坐起阅读 11,661评论 0 23
  • 看简书里有人写的挺有意思,也来凑凑热闹。 1 你穿一袭紫罗兰打我身边掠过 周边的灯红酒绿 都变成了沙漠 2 我本是...
    翁小唐阅读 176评论 2 2
  • 这不上周三霉霉和抖森的分手迅速成为了娱乐版头条新闻,而屯长作为吃瓜群众看完热闹后,不经开始思考一个严肃的问题---...
    MCMarty阅读 1,519评论 0 0
  • 今天上午我送儿女去学书法,到了书法班,李老师一再表扬她俩学的认真,努力,下午我们三人先一起占了点画,后来儿...
    梁佳硕妈妈阅读 226评论 0 1

友情链接更多精彩内容