算法虐我千百遍,我待算法仍如初恋(七)

来了来了,今天来分享一个力扣上评价困难的题目------接雨水(Leetcode 42题)。当时在写成最多水的容器这道题目的时候,就听说还有道接雨水的题目。今天终于让我见到真实面貌了。话不多说,直接开始正题吧!这道题目的主要的算法思想还是双指针哦!因为我现在专门学习做双指针。

# 手刃算法第八式:接雨水

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

题目分析

刚拿到这道题目的时候我就感觉有点摸不到头脑。从示例上可以知道题目的意思,就是看这些坑里面能积多少水。首先我的想法就是,设置一个起始点,然后找到其左边最高的,再找到其右边最高的,然后根据木桶效应,取最短的那边就可以减去它本身的高度就可以得到起始点最多能接多少雨水,然后继续得到下一个起始点能接的雨水量。

emmmm,听着就好麻烦。

看这个图是不是就直观一点了。应该是直观了一点。

这时候就要写代码实现了!

代码实现

通过刚才的算法分析,编写如下的代码:

ini 复制代码
var trap = function(height) {
    let sum = 0;
    let len = height.length - 1;
    for (let i = 1; i < len; i++) {
        let right = i + 1;
        let left = i - 1;
        let maxLeft = height[i];
        let maxRight = height[i];
        while (left >= 0) {
            maxLeft = Math.max(maxLeft, height[left]);
            left--;
        }
        while (right <= len) {
            maxRight = Math.max(maxRight, height[right]);
            right++;
        }
        let waterLevel = Math.min(maxLeft, maxRight);
        sum += Math.max(0, waterLevel - height[i]);
    }
    return sum;
}

通过这个来运行的话还是能运行出来的。

但是!!!服了,提交的时候给我来个这个!

我只能说,6啊!还是我的代码不够完美。哎,可是这已经是我能写的出来的了。

没办法只能去寻求帮助了。

别人家的想法

直接设置左右两个指针,一个指针指向数组头部,一个指针指向数组尾部,然后 设置两个变量分别记录左右两边的最大高度。如果左边的高度小于右边的高度,则用左边的最大高度减去左边当前的高度就是此时这个格子能接到的雨水量。相反就用右边最大高度减去右边当前的高度。语言表达能力有限,感觉讲清楚了,有感觉没有说清楚。 还是看图说话吧!!!

他这个想法和我的是差不多的,但是还是挺猛的!这样就不需要用两个循环了,一个循环就搞定了。

具体代码实现

ini 复制代码
var trap = function(height) {
    if (height.length === 0) return 0;
    
    let left = 0, right = height.length - 1; 
    let maxLeft = 0, maxRight = 0; 
    let sum = 0; // 初始化积水总量

    while (left < right) {
        if (height[left] <= height[right]) {
            maxLeft = Math.max(maxLeft, height[left]);
            sum += maxLeft - height[left];
            left++;
        } else {
            maxRight = Math.max(maxRight, height[right]);
            sum += maxRight - height[right];
            right--;
        }
    }
    return sum;
}

在回过头来看我写的代码,就跟现在看小学生的作文一样。我咋就想不到呢,同样都是双指针,咋差距这么大。难受了~

学到了学到了!以后再碰到要学会这样!

结语

这道题目说实话对我来说还是有难度的,不过当理清楚了还是可以拿下的。虽然我的代码比较low,但是最起码写出来了,也算是个进步吧!在b站上学习这个,好像说还有一种单调栈的方法,emmm,单调栈是啥,有没有大佬可以给解答一下的。今晚就到这里,晚安啦,明天也要努力哦!

相关推荐
多多*13 分钟前
线程池相关 FutureTask介绍 处理阻塞 Future改进->CompletableFuture
java·开发语言·后端·python·spring
高神龙拒绝做个菜鸟13 分钟前
常见兼容性问题
前端·性能优化
梦仔生信进阶1 小时前
基于R计算皮尔逊相关系数
前端·数据库·r语言
Quantum&Coder1 小时前
Swift语言的软件工程
开发语言·后端·golang
liuweidong08021 小时前
【Pandas】pandas Series rtruediv
前端·javascript·pandas
吴代庄2 小时前
复盘成长——2024年终总结
后端
布兰妮甜2 小时前
px、em 和 rem 的区别:深入理解 CSS 中的单位
前端·css·px-em-rem·布局技巧·css单位
CyberScriptor2 小时前
CSS语言的语法糖
开发语言·后端·golang
我想学LINUX3 小时前
【2024年华为OD机试】(C卷,100分)- 攀登者1 (Java & JS & Python&C/C++)
java·c语言·javascript·c++·python·游戏·华为od
然后就去远行吧5 小时前
小程序组件 —— 31 事件系统 - 事件绑定和事件对象
前端·javascript·小程序