算法系列——接雨水

206 阅读1分钟

题目

原题链接:leetcode.cn/problems/tr… 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

在这里插入图片描述

思路

  1. 暴力解法:

不断循环,找到height[1,i-1] height[i+1,height.length-2] 两者之间的较小值

复杂度:时间复杂度O(n²) 空间复杂度O(1)

  1. 双指针解法:

准备双指针,分别指向数组首尾元素,代表最初的两个边界;指针往中间遍历,遇到更低柱子就是底,用较短的边界减去底就是 这一列的接水量,遇到更高的柱子就是新的边界,更新边界大小

复杂度: 时间复杂度O(n) 空间复杂度O(1)

代码

  1. 暴力解法
class Solution {
    public int trap(int[] height) {
        //  暴力方法 两边最大值的 取较小值
        int result=0;
        for(int i=1;i<height.length-1;i++){
            //找到左边最大值
            int maxLeft=0;
            int maxRight=0;
            for(int m=0;m<i;m++){
                maxLeft=Math.max(maxLeft,height[m]);
            }
            //找到右边最大值
            for(int n=i+1;n<height.length;n++){
                 maxRight=Math.max(maxRight,height[n]);
            }
            //取两者中间较小的
            int max=Math.min(maxLeft,maxRight);
            //只有高于height[i] 才能盛水
            if(max>height[i]){
                result+=max-height[i];
            }
        }
        return result;
    }
}

  1. 双指针解法
class Solution {
    public int trap(int[] height) {
       
        //双指针法
        //准备双指针,分别指向数组首尾元素,代表最初的两个边界
        // 指针往中间遍历,遇到更低柱子就是底,用较短的边界减去底就是 这一列的接水量,遇到更高的柱子就是新的边界,更新边界大小 
        // Index(maxLeft) <= left  Index(maxRight)>= right
        int result=0;
        int l=0;
        int r=height.length-1;
        int maxLeft=0;
        int maxRight=0;
        while(l<r){
            maxLeft=Math.max(maxLeft,height[l]); 
            maxRight=Math.max(maxRight,height[r]); 
            if(maxLeft<maxRight){
                result+=maxLeft-height[l];
                l++;
            }
            else{
                result+=maxRight-height[r];
                r--;
            }
        }

        return result;

    }
}