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

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

给定 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]

三、结语

再见!

相关推荐
肖师叔爱抽风1 分钟前
使用nvm use切换版本时出现虚假成功信息,使用nvm ls,实际显示没有切换成功,解决方法
前端
猩猩程序员3 分钟前
Rust为什么需要Borrow Trait
前端
BUG收容所所长3 分钟前
Zustand状态管理如何驱动低代码平台的数据流?
前端·javascript·设计
司宸7 分钟前
学习笔记十四 —— 嵌套JSON树结构 实现模糊匹配返回搜索路径
前端
盗德8 分钟前
Vue渲染引擎的范式革命:从虚拟DOM到Vapor模式
前端·vue.js
BUG收容所所长8 分钟前
React递归渲染与react-dnd——低代码平台的组件拖拽与动态渲染实践
前端·javascript·设计
阿华的代码王国25 分钟前
【Android】日期选择器
android·xml·java·前端·后端
爱吃KFC的大肥羊28 分钟前
C/C++常用字符串函数
c语言·数据结构·c++·算法
im_AMBER31 分钟前
Leetcode 11 java
java·算法·leetcode
丶小鱼丶39 分钟前
二叉树算法之【Z字型层序遍历】
java·算法