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


相关推荐
重生之我是Java开发战士2 分钟前
【数据结构】优先级队列(堆)
java·数据结构·算法
菜鸟233号2 分钟前
力扣216 组合总和III java实现
java·数据结构·算法·leetcode
大柏怎么被偷了3 分钟前
【Linux】重定向与应用缓冲区
linux·服务器·算法
dodod20125 分钟前
Ubuntu24.04.3执行sudo apt install yarnpkg 命令失败的原因
java·服务器·前端
Evan芙6 分钟前
搭建 LNMT 架构并配置 Tomcat 日志管理与自动备份
java·架构·tomcat
AuroraWanderll6 分钟前
类和对象(三)-默认成员函数详解与运算符重载
c语言·开发语言·数据结构·c++·算法
青云交8 分钟前
Java 大视界 -- Java+Spark 构建企业级用户画像平台:从数据采集到标签输出全流程(437)
java·开发语言·spark·hbase 优化·企业级用户画像·标签计算·高并发查询
铉铉这波能秀12 分钟前
正则表达式从入门到精通(字符串模式匹配)
java·数据库·python·sql·正则表达式·模式匹配·表格处理
Liangwei Lin15 分钟前
洛谷 P10471 最大异或对 The XOR Largest Pair
算法
sin_hielo15 分钟前
leetcode 3652(定长滑动窗口/前缀和)
数据结构·算法·leetcode