zoukankan      html  css  js  c++  java
  • 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;
        }
    }
    
  • 相关阅读:
    Swap Nodes in Pairs
    Permutations(copy)
    Sort Colors
    Merge Two Sorted Lists
    Implement Queue using Stacks
    Best Time to Buy and Sell Stock
    Happy Number
    Gray Code
    springMVC初次搭建,产生错误
    JSP常用指令
  • 原文地址:https://www.cnblogs.com/XT-xutao/p/12633043.html
Copyright © 2011-2022 走看看