当前位置:首页 > 技术 > 正文内容

接雨水问题大厂面试高频解析:算法核心与实战技巧

访客 技术 2026年7月6日 1

在算法面试中,LeetCode 42号题"接雨水"是字节跳动、腾讯等公司的常客,出现概率高达70%。本题要求计算一组非负整数代表柱子高度图所能承接的雨水量。

示例:
输入:height = [0,1,0,2,1,0,1,3,2,1,2,1]
输出:6
解释:柱子之间凹陷区域可以存储雨水。

难度:中等偏难 | 面试频率:字节跳动(高)、腾讯(高)、阿里巴巴(中高)

算法解析:从"接水"到"边界"的思维突破

核心在于转换问题视角:不要关注水本身,而是关注每个位置的左右两侧边界。

解法一:动态规划(推荐)

通过预处理每个柱子的左右最大边界值,降低计算复杂度。


public int trapWater(int[] heights) {
    int n = heights.length;
    if (n == 0) return 0;

    int[] leftBoundary = new int[n];
    int[] rightBoundary = new int[n];

    leftBoundary[0] = heights[0];
    for (int i = 1; i < n; i++) {
        leftBoundary[i] = Math.max(leftBoundary[i-1], heights[i]);
    }

    rightBoundary[n-1] = heights[n-1];
    for (int i = n-2; i >= 0; i--) {
        rightBoundary[i] = Math.max(rightBoundary[i+1], heights[i]);
    }

    int totalWater = 0;
    for (int i = 0; i < n; i++) {
        totalWater += Math.min(leftBoundary[i], rightBoundary[i]) - heights[i];
    }
    return totalWater;
}

时间复杂度:O(n) | 空间复杂度:O(n)

解法二:双指针(空间优化)

通过左右指针动态跟踪边界,无需额外数组。


public int trapWater(int[] heights) {
    int left = 0, right = heights.length - 1;
    int leftMax = 0, rightMax = 0;
    int total = 0;

    while (left < right) {
        if (heights[left] < heights[right]) {
            if (heights[left] >= leftMax) {
                leftMax = heights[left];
            } else {
                total += leftMax - heights[left];
            }
            left++;
        } else {
            if (heights[right] >= rightMax) {
                rightMax = heights[right];
            } else {
                total += rightMax - heights[right];
            }
            right--;
        }
    }
    return total;
}

时间复杂度:O(n) | 空间复杂度:O(1) - 极致优化

解题方法论核心

  • 问题转化:将"接水"抽象为"边界计算"
  • 预处理思维:用空间换时间,降低时间复杂度
  • 双指针策略:左右夹击,动态更新边界
  • 木桶原理:水位由最短边界决定

"不要被题目表象迷惑,找到问题的本质特征"

面试扩展题型

  • 三维接雨水(LeetCode 407题):升级到三维空间,需使用最小堆
  • 盛最多水的容器(LeetCode 11题):类似双指针应用,但计算逻辑不同
  • 柱状图中最大矩形(LeetCode 84题):柱状图变体,使用单调栈解决

学习路径建议

基础先行:掌握数组、链表、树、图等基本数据结构。
思维训练:精练100道核心高频题。
实战演练:参与模拟面试提升应变能力。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

linux screen 用法详情 (nohup 的替代方案)

一、screen 是什么?能干嘛?screen 是一个终端复用器,可以:在一个 SSH 会话中开多个“虚拟终端”SSH 断线后,程序仍然在后台运行随时重新连接到原来的会话特别适合:nohup 的替代方案跑脚本 / 爬虫 / 训练模型运维、远程开发二、安装 screen# CentOS / Rocky / Almayum install -y screen# Debian / Ubuntuapt i...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。