leetcode 42 接雨水

梦想与她 提交于 2020-04-06 10:28:14

原题点这里

这个题刚开始看,一点思路也没有呀。。。。然后就迫不及待的看了题解。也不知道什么时候能积累出量变

这个题虽然标记为困难,但是其实不难。最简单的办法,我们计算每个位置的储水量:Min(maxL,maxR)-height[i]

我们在计算i位置上的储水量,分别向左向右找到最大值即可。 124ms

public static int trap(int[] height) {

        int len = height.length;
        if (len <= 2) return 0;
        int ans = 0;
        for (int i = 1; i < len - 1; i++) {
            int maxLeft = 0;
            int maxRight = 0;
            for (int j = i - 1; j >= 0; j--) {
                maxLeft = Math.max(maxLeft, height[j]);
            }
            for (int j = i + 1; j < len; j++) {
                maxRight = Math.max(maxRight, height[j]);
            }
            int cur = Math.min(maxLeft, maxRight) - height[i];
            ans += cur > 0 ? cur : 0;
        }
        return ans;
    }
View Code

 

仔细思考一下,我们不停的向左、向右(向前看~~,不知不觉的唱了起来呢)寻找最大值,其实可以通过一次遍历,然后记录下来最大值

maxL[i]表示 i以左的最大值,maxR[i]表示i以右的最大值。

在稍微思考一下,maxL maxR应该是包含i本身的。于是   2ms

public static int trap2(int[] height) {

        int len = height.length;
        if (len <= 2) return 0;
        int[] maxLeft = new int[len];
        int[] maxRight = new int[len];
        maxRight[len - 1] = height[len - 1];
        maxLeft[0] = height[0];
        for (int i = 1; i < len; i++)
            maxLeft[i] = Math.max(maxLeft[i - 1], height[i]);
        for (int i = len - 2; i >= 0; i--)
            maxRight[i] = Math.max(maxRight[i + 1], height[i]);
        int ans = 0;
        for (int i = 1; i < len - 1; i++) {
            int cur = Math.min(maxLeft[i], maxRight[i]) - height[i];
            ans += cur;
        }
        return ans;
    }
View Code

 

我们在深入思考一下,可以用栈来存储没有计算储水值的索引。 当 height[i]>height[stack.peek()]的时候,第i个位置就可以和栈中的下一个索引,形成一个容器,在索引statck.peek这里储水。直到栈被清空,所有能储水的位置就被计算完成了。

我们计算出所有位置,就可以得到结果。  4ms

public static int trap3(int[] height) {

        int len = height.length;
        if (len <= 2) return 0;

        int ans = 0;
        Stack<Integer> s = new Stack();
        int cur = 0;
        while (cur < len) {
            while (!s.empty() && height[cur] > height[s.peek()]) {
                int top = s.peek();
                s.pop();
                if (s.empty()) break;
                int wid = cur - s.peek() - 1;
                int hei = Math.min(height[cur], height[s.peek()]) - height[top];
                ans += hei * wid;
            }
            s.push(cur++);
        }
        return ans;

    }
View Code

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!