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

来了来了,今天来分享一个力扣上评价困难的题目------接雨水(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,单调栈是啥,有没有大佬可以给解答一下的。今晚就到这里,晚安啦,明天也要努力哦!

相关推荐
步行cgn2 小时前
Spring 基于 XML 的自动装配:byName 详解
java·后端·spring
野槐2 小时前
前端项目优化(有了我,会发生...)
前端
幸运小圣3 小时前
PointerEvent 常用属性与事件整理【JavaScript】
开发语言·javascript·ecmascript
aa小小3 小时前
【无标题】
前端
RISCV_Explorer4 小时前
RISC-V启动与运行时规范机制解析——BRS约定、HSM多核启动与设备树要求
后端·risc-v
星栈独行4 小时前
ADK-Rust 是什么?Rust 生态新一代 AI Agent 开发套件
人工智能·后端·rust
计算机魔术师4 小时前
还在单线程跟 AI 聊天?Claude Code 并行多会话让你一个人干三个人的活
前端
志尊宝4 小时前
Vue3 零基础每日笔记(038):亲手封装 useDebounceFn 与 useThrottleFn——高频事件的流量阀
前端·javascript·vue·html·vue3
JavaGuide4 小时前
对标 MinIO!全新一代分布式文件系统正式发布
前端·后端
风骏时光牛马4 小时前
AI驱动自动化业务工作流搭建实践
前端