一分钟解决 | 高频面试算法题——接雨水(双指针最优解)

一、 题目描述------接雨水

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

示例 1:

css 复制代码
输入: height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出: 6
解释: 上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。 

示例 2:

css 复制代码
输入: height = [4,2,0,3,2,5]
输出: 9

提示:

  • n == height.length
  • 1 <= n <= 2 * 104
  • 0 <= height[i] <= 105

二、题解(双指针)

js 复制代码
/**
 * @param {number[]} height
 * @return {number}
 */
var trap = function(height) {
    let left = 0;
    let right = height.length - 1;
    let leftMax = 0;
    let rightMax = 0;
    let ans = 0;
    
    while (left < right) {
        if (height[left] < height[right]) {
            height[left] >= leftMax 
                ? leftMax = height[left] 
                : ans += leftMax - height[left];
            left++;
        } else {
            height[right] >= rightMax 
                ? rightMax = height[right] 
                : ans += rightMax - height[right];
            right--;
        }
    }
    return ans;
};

核心思想(双指针)

  1. 双指针法: 使用两个指针 leftright 分别从数组的两端向中间移动。

  2. 短板效应与动态维护最大高度:

    • 短板效应: 每个位置能够接到的雨水高度,取决于它左右两侧最大高度的 较小值(也就是"短板")。 就像木桶原理一样,水位的高度取决于最短的那块木板。
    • 动态维护最大高度: 通过 leftMax 维护左侧的最大高度,通过 rightMax 维护右侧的最大高度。在移动指针的过程中,不断更新这两个变量。
    • 计算雨水: 每次移动指针,都判断当前位置可以接到的雨水,并累加到 ans 中。如果当前高度小于两侧的最大高度,就可以接到雨水。 雨水的高度等于较小侧的最大高度减去当前高度。如果当前高度大于两侧最大高度,则更新最大高度。

一些细节

  • 为什么移动较小的一侧?

    • 每次比较 height[left]height[right],总是移动 较小的那一侧 。 这是因为只有移动较小的一侧,才 有可能 遇到更高的柱子,从而抬高短板,增加能够接到的水量。 如果移动较大的一侧,短板仍然是较小的一侧,接水量不会增加。
  • 根据短板计算雨水:

    • 如果 height[left] < height[right],那么 left 指针的位置能接到的水量,是由左边的最大高度 leftMax 决定的。计算公式为 leftMax - height[left]
    • 如果 height[left] >= height[right],那么 right 指针的位置能接到的水量,是由右边的最大高度 rightMax 决定的。计算公式为 rightMax - height[right]

三、结语

再见!

相关推荐
闻闻不会编程4 分钟前
704. 二分查找 (力扣)
数据结构·算法·leetcode
xzboss5 分钟前
DOM转矢量PDF
前端·javascript
一无所有不好吗6 分钟前
纯前端vue项目实现版本更新(纯代码教程)
前端
AndrewHZ10 分钟前
【图像处理基石】立体匹配的经典算法有哪些?
图像处理·算法·计算机视觉·滤波·模式识别·立体匹配
AndrewHZ14 分钟前
【图像处理入门】4. 图像增强技术——对比度与亮度的魔法调节
图像处理·算法·计算机视觉·几何变换·图像增强·模式识别
安全系统学习19 分钟前
内网横向之RDP缓存利用
前端·安全·web安全·网络安全·中间件
bxlj_jcj22 分钟前
解锁Java多级缓存:性能飞升的秘密武器
java·缓存·面试·架构
Hilaku26 分钟前
为什么我不再相信 Tailwind?三个月重构项目教会我的事
前端·css·前端框架
FogLetter27 分钟前
JavaScript 的历史:从网页点缀到改变世界的编程语言
前端·javascript·http
鹏北海29 分钟前
Vue3+TS的H5项目实现微信分享卡片样式
前端·微信