• LeetCode42-接雨水


    题目描述

    给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

    我的题解

    关键在于找到全部可以装雨水的'槽'
    从第一个柱子开始,寻找第一个比它高的,即可组成一个槽。
    如果没有更高的,就找到后面最高的,这时也可以组成一个槽

        //99.98%
        public int trap(int[] height) {
            int len = height.length;
            int rainCount = 0;//雨量
            for (int i=0;i<len-1;i++){
                if (height[i+1]>height[i])continue;//如果这个柱子比下一个低,跳过。
                int highter = height[i];//后面更高的柱子高度
                int highterIndex = i;//后面更高的柱子索引
                int max = height[i+1];//后面的最高柱子
                int maxIndex = i+1;//后面的最高柱子索引
                boolean hasHighter = false;//后面是否存在比当前柱子更高的柱子
                for (int j=i+1;j<len;j++){
                    if (height[j]>=highter){//找到不低于当前柱子的柱子
                        highterIndex = j;
                        hasHighter = true;
                        break;
                    }
                    if (height[j]>max){//计算后面最高的
                        max = height[j];
                        maxIndex = j;
                    }
                }
                if (!hasHighter) {//如果后面没有更高的柱子,就是用后面的最高柱子
                    highterIndex = maxIndex;
                    highter = max;
                }
                for (int j=i+1;j<highterIndex;j++){//计算这个槽可以积累的雨量
                    rainCount+=highter-height[j];
                }
                i=highterIndex-1;//跳到这个槽的右边柱子
            }
            return rainCount;
        }
    

    分析:
    时间复杂度:O(N),虽然看似有来两个循环,但是他们是线性的
    空间复杂度: O(1),只使用了几个变量而已

    其他解法

    单调栈

    public class Solution {
        public int trap(int[] height) {
            if (height == null) {
                return 0;
            }
            Stack<Integer> stack = new Stack<>();
            int ans = 0;
            for (int i = 0; i < height.length; i++) {
                while(!stack.isEmpty() && height[stack.peek()] < height[i]) {
                    int curIdx = stack.pop();
                    // 如果栈顶元素一直相等,那么全都pop出去,只留第一个。
                    while (!stack.isEmpty() && height[stack.peek()] == height[curIdx]) {
                        stack.pop();
                    }
                    if (!stack.isEmpty()) {
                        int stackTop = stack.peek();
                        // stackTop此时指向的是此次接住的雨水的左边界的位置。右边界是当前的柱体,即i。
                        // Math.min(height[stackTop], height[i]) 是左右柱子高度的min,减去height[curIdx]就是雨水的高度。
                        // i - stackTop - 1 是雨水的宽度。
                        ans += (Math.min(height[stackTop], height[i]) - height[curIdx]) * (i - stackTop - 1);
                    }
                }
                stack.add(i);
            }
            return ans;
        }
    }
    
  • 相关阅读:
    temp
    Windows如何利用输入法简单的打出 ‘↑’ ‘↓’ ‘↖’等箭头
    Win10系统特别卡的一个原因
    巨蟒python全栈开发-第16天 核能来袭-初识面向对象
    在pycharm中误删了Python文件,怎么办,挺急的?
    巨蟒python全栈开发-第15天 装饰器
    巨蟒python全栈开发-第13天 内置函数 匿名函数lambda
    巨蟒python全栈开发-第12天 生成器函数 各种推导式 yield from
    360浏览器的收藏夹隐藏了,怎么处理?
    如何解决安装好的google浏览器打不开网页的问题?
  • 原文地址:https://www.cnblogs.com/XT-xutao/p/12633043.html
Copyright © 2020-2023  润新知