LeetCode算法题:42. 接雨水(Java)

题目描述

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

示例 1:

复制代码
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 

示例 2:

复制代码
输入:height = [4,2,0,3,2,5]
输出:9

提示:

  • n == height.length
  • 1 <= n <= 2 * 10^4
  • 0 <= height[i] <= 10^5

解题思路:

1.暴力解答:

每个位置处的积水取决于左右两边柱子的最低高度,分别从起始位置遍历到该位置得到左边的最高高度,然后从该位置遍历到末端,得到右边高度的最高值。因此计算每个位置处的积水量:等于该位置左右两边最高高度的最小值-该位置的高度。

代码:

java 复制代码
class Solution {
    public static int trap(int[] height) {
        int sumVolume = 0;
        int i=0,len=height.length;
        for(;i<len;i++){
            int j=0,leftmax = i;
            while(j<i){
                if(height[j]>height[leftmax])leftmax = j;
                j++;
            }
            j=i+1;
            int rightmax = i;
            while(j<len){
                if(height[j]>height[rightmax])rightmax = j;
                j++;
            }
            sumVolume+=Math.min(height[leftmax],height[rightmax])-height[i];
        }
        return sumVolume;
    }
}

结果:

2.动态规划

上述暴力解法由于每次遍历i时都又遍历了一整遍数组,因此时间复杂度为O(n^2),导致运行时间超时。因此采用动态规划的思想,提前遍历数组,确定好每个位置处的左边最高值和右边最高值。然后再按上述计算积水量方法计算总的积水量即可。

代码:

java 复制代码
class Solution {
    public static int trap(int[] height) {
        int sumVolume = 0;
        int i=0,len=height.length;
        int curMaxHeight = 0;
        int[] leftMaxheigt = new int[len]; // 存储每个位置左边最高值
        int[] rightMaxheigt = new int[len]; // 存储每个位置右边最高值
        for(;i<len;i++){// 从前往后遍历height数组获取每个位置左边最高值
            if(height[i]>curMaxHeight){
                curMaxHeight = height[i];
            }
            leftMaxheigt[i] = curMaxHeight;
        }
        curMaxHeight=0;
        for(i=len-1;i>=0;i--){// 从后往前遍历height数组获取每个位置右边最高值
            if(height[i]>curMaxHeight){
                curMaxHeight = height[i];
            }
            rightMaxheigt[i] = curMaxHeight;
        }
        for(i=0;i<len;i++){
            sumVolume+=Math.min(leftMaxheigt[i],rightMaxheigt[i])-height[i];
        }
        return sumVolume;
    }
}

结果:

3.双指针

java 复制代码
class Solution {
    public static int trap(int[] height) {
        int i=0,j=height.length-1;
        int leftMax=0,rightMax=0;
        int sumVolume=0;
        while(i<j){
            if(height[i]<height[j]){
                if(height[i]<leftMax){
                    sumVolume += leftMax-height[i];
                }else{
                    leftMax=height[i];
                }
                i++;
            }else{
                if(height[j]<rightMax){
                    sumVolume += rightMax-height[j];
                }else{
                    rightMax=height[j];
                }
                j--;
            }
        }
        return sumVolume;
    }
}

结果:

相关推荐
毕设源码-朱学姐4 小时前
【开题答辩全过程】以 工厂能耗分析平台的设计与实现为例,包含答辩的问题和答案
java·vue.js
智者知已应修善业5 小时前
【求中位数】2024-1-23
c语言·c++·经验分享·笔记·算法
地平线开发者5 小时前
PTQ 量化数值范围与优化
算法·自动驾驶
sali-tec6 小时前
C# 基于halcon的视觉工作流-章68 深度学习-对象检测
开发语言·算法·计算机视觉·重构·c#
测试人社区-小明6 小时前
智能弹性伸缩算法在测试环境中的实践与验证
人工智能·测试工具·算法·机器学习·金融·机器人·量子计算
Spring AI学习6 小时前
Spring AI深度解析(9/50):可观测性与监控体系实战
java·人工智能·spring
罗西的思考6 小时前
【Agent】MemOS 源码笔记---(5)---记忆分类
人工智能·深度学习·算法
java1234_小锋7 小时前
Spring IoC的实现机制是什么?
java·后端·spring
xqqxqxxq7 小时前
背单词软件技术笔记(V2.0扩展版)
java·笔记·python
消失的旧时光-19437 小时前
深入理解 Java 线程池(二):ThreadPoolExecutor 执行流程 + 运行状态 + ctl 原理全解析
java·开发语言