力扣42.接雨水

文章目录

一、前言

接雨水,这道题我在大学的时候就听说这道题是力扣的难题,但是一直没有做过。

这几天在网上偶然看到关于这道题的文章,于是去学了学这两题的解题思路,故写下这篇博客记录记录。

力扣链接:力扣42. 接雨水


二、前后缀分解

前后缀分解的思路就是把每一个下标看作一个桶,当前下标的值看作通底高度,这个桶能装多少水,取决于桶的左边的最大值、右边最大值以及桶的高度。

那能装多少水,这个取决于左右最大高度的最小值,以及桶底的高度

比如下图这个桶,左边最大值为2,右边最大值为3,桶底高度为0,所以这个桶能装单位为2的水。

再比如,下面这个桶,左边最大高度为2,右边最大高度为3,桶底高度为1,那么能装单位为1的水。

这个思路需要两个数组辅助实现,数组A负责存放当前下标对应的左边桶高度的最大值,数组B对应存放的是右边桶高度的最大值。

java 复制代码
class Solution {
    public int trap(int[] height) {
        int result = 0;
        // 左边最大值
        int[] larr = new int[height.length];
        // 右边最大值
        int[] rarr = new int[height.length];
        for (int i = 1; i < height.length; i++) {
            larr[i] = Math.max(height[i - 1], larr[i - 1]);
        }
        for (int i = height.length - 2; i >= 0 ; i --) {
            rarr[i] = Math.max(height[i + 1], rarr[i + 1]);
        }
        // 左边最大 右边最大值取最小值,然后再再减去自身高度,就是能装多少水的容量
        for (int i = 0; i < height.length; i++) {
            int sum = Math.min(larr[i], rarr[i]) - height[i];
            if (sum > 0){
                result += sum;
            }
        }
        return result;
    }
}

时间复杂度:O(n),这里遍历了三次height数组,对应的时间复杂度是O(3n),也就是O(n)

空间复杂度:O(n),额外申请了两个长度为n的数组,所以空间复杂度为O(n).


三、双指针

对于上面的解法,时间复杂度肯定是不能再降低了,因为要找出所有能接多少雨水,肯定要都遍历一遍,故时间复杂度O(n)是最小的时间复杂度了。

那么只好想办法降低空间复杂度了。

这里需要明确一个点,就是这个桶能接多少雨水,取决于左右边最小的那个值

这里需要分类讨论一下:

对于某一点上的一个桶,知道这个桶左边的最大值(A),同时知道右边某一个区间中的最大值(B)

  1. A < B,那么当前位置能接多少水,就取决于A,和B没有关系,接的雨水 = A - 桶底高度,就可以计算当前位置能接多少水,下面左边位置可以往后移动一个单位
  2. A > B,那么当前位置能接多少水,就取决于B,和A没有关系,接的雨水 = B - 桶底高度
  3. 就可以计算当前位置能接多少水,下面左边位置可以往前移动一个单位
  4. A = B,取A 还是 B 都没关系。
java 复制代码
public int trap(int[] height) {
    int result = 0;
    int l = 0, r = height.length - 1;
    int preMax = 0, sufMax = 0;
    while (l <= r){
        preMax = Math.max(preMax, height[l]);
        sufMax = Math.max(sufMax, height[r]);
        if (preMax < sufMax){
            result += preMax - height[l];
            l ++;
        }else {
            result += sufMax - height[r];
            r --;
        }
    }

    return result;
}

时间复杂度:O(n),这里遍历了一次height数组,也就是O(n)

空间复杂度:O(1),没有额外申请空间,只用了额外变量。


相关推荐
旖-旎5 分钟前
哈希表(存在重复元素||)(4)
数据结构·c++·算法·leetcode·哈希算法·散列表
Lyyaoo.6 分钟前
【JAVA基础面经】线程的状态
java·开发语言
Hello小赵7 分钟前
C语言如何自定义链接库——编译与调用
android·java·c语言
Run_Teenage7 分钟前
Linux:认识信号,理解信号的产生和处理
linux·运维·算法
希望永不加班11 分钟前
SpringBoot 配置绑定:@ConfigurationProperties
java·spring boot·后端·spring
悟空码字12 分钟前
MySQL性能优化的天花板:10条你必须掌握的顶级SQL分析技巧
java·后端·mysql
indexsunny15 分钟前
互联网大厂Java面试实战:Spring Boot、MyBatis与Kafka在电商场景中的应用
java·spring boot·面试·kafka·mybatis·电商·技术栈
programhelp_16 分钟前
字节跳动(ByteDance)2026 OA 面经|高频题型拆解 + 速通攻略
面试
殷紫川20 分钟前
CompletableFuture 异步编程全解:核心能力、编排方案、异常处理与超时控制
java
無限進步D23 分钟前
蓝桥杯赛前刷题
c++·算法·蓝桥杯·竞赛