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


相关推荐
月明长歌几秒前
【码道初阶】一道经典简单题:多数元素(LeetCode 169)|Boyer-Moore 投票算法详解
算法·leetcode·职场和发展
IT_Octopus4 分钟前
Java GZip 压缩实践 +实践思考 +进一步压榨性能和存储方案思考:Protobuf+ GZip
java·spring boot
wadesir6 分钟前
C语言模块化设计入门指南(从零开始构建清晰可维护的C程序)
c语言·开发语言·算法
t198751289 分钟前
MATLAB水声信道仿真程序
开发语言·算法·matlab
毕设源码-郭学长40 分钟前
【开题答辩全过程】以 高校教材大管家系统为例,包含答辩的问题和答案
java·spring boot
Gavin在路上1 小时前
DDD之用事件风暴重构“电商订单履约”(11)
java·前端·重构
AnAnCode1 小时前
ECS 架构 (Entity Component System) - 数据导向编程快速入门
java·架构·游戏服务器
qq_12498707531 小时前
基于SpringBoot+vue的小黄蜂外卖平台(源码+论文+部署+安装)
java·开发语言·vue.js·spring boot·后端·mysql·毕业设计
小二·1 小时前
Spring框架入门:TX 声明式事务详解
java·数据库·spring
i02081 小时前
Java 17 + Spring Boot 3.2.5 使用 Redis 实现“生产者–消费者”任务队列
java·spring boot·redis