力扣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),没有额外申请空间,只用了额外变量。


相关推荐
不懂英语的程序猿2 分钟前
【JEECG 组件扩展】JSwitch开关组件扩展单个多选框样式
java·前端·javascript·后端
Running_C8 分钟前
必知的http常见请求方法和状态码,让你怼后端更有底气
前端·面试
hqxstudying11 分钟前
Java行为型模式---命令模式
java·开发语言·后端·eclipse·命令模式
weixin_5247499616 分钟前
OkHttp 框架封装一个 HTTP 客户端,用于调用外部服务接口
java·后端
泉城老铁18 分钟前
Spring Boot 对接 Modbus 协议并获取点表数据的详细指南
java·后端·物联网
秋秋棠31 分钟前
MyBatis延迟加载(Lazy Loading)之“关联查询”深度解析与实践
java·mybatis
ZsTs11939 分钟前
吃透前端项目优化系列(二):首屏渲染优化 + 性能指标拆解
前端·面试
菜市口的跳脚长颌42 分钟前
面试备战录
前端·面试
ggdpzhk44 分钟前
Java :List,LinkedList,ArrayList
java·开发语言·list
前端付豪1 小时前
1、✅彻底搞懂 call、apply 和 bind
前端·javascript·面试