lc42接雨水

news2025/5/19 2:29:08

1.原题

42. 接雨水 - 力扣(LeetCode)

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

2.题目解析

这一题是经常被考到的一道算法题,其中最简单最好用的方法就是双指针,今天我们就以双指针的角度来解决这一题!

2.1动态规划写法

我们先从动态规划的角度引入双指针的视角!

在计算数组height中下标i处接雨水量时,存在这样一个规律:下雨后水在该位置能达到的最大高度,等同于i两侧高度中的最小值,而i处实际能承接的雨水量,就是这个最大高度减去height[i]的值。

如果采用最基础的解决方式,针对数组height里的每一个元素,都需要分别朝左、右方向进行扫描,记录下左右两边的最大高度,进而算出每个下标位置能承接的雨水量。若数组height长度为n,由于对每个下标位置进行左右扫描都要耗费O(n)的时间,最终整体的时间复杂度会达到O(n²) 。

这种基础做法之所以耗时较长,根源在于对每个下标位置都要重复执行左右扫描操作。要是能提前获取每个位置两侧的最大高度,就能将计算能接雨水总量的时间复杂度降至O(n)。借助动态规划的思路,恰好可以在O(n)时间内预先处理并得到每个位置两侧的最大高度。

具体操作时,我们构建两个长度同为n的数组leftMax和rightMax。其中,leftMax[i]代表从数组起始位置到下标i这一范围内,height的最大高度;rightMax[i]则表示从下标i到数组末尾,height的最大高度。

不难发现,leftMax数组的第一个元素leftMax[0],其值就等于height[0];rightMax数组的最后一个元素rightMax[n - 1],对应的值为height[n - 1]。至于两个数组的其他元素,计算规则如下:

  • 当1 ≤ i ≤ n - 1时,leftMax[i]取leftMax[i - 1]和height[i]中的较大值;
  • 当0 ≤ i ≤ n - 2时,rightMax[i]是rightMax[i + 1]和height[i]中的较大值。

基于此,我们可以通过正向遍历数组height,逐个算出leftMax数组的元素值;再反向遍历数组height,得到rightMax数组的每个元素值。

在获取leftMax和rightMax数组的全部元素值后,对于0 ≤ i < n范围内的每个i,其下标位置能承接的雨水量就等于min(leftMax[i], rightMax[i]) - height[i]。最后,遍历所有下标位置,将每个位置的接雨水量累加起来,便能得到最终能承接的雨水总量。

2.2引入双指针写法

在动态规划解法中,需借助leftMax和rightMax两个数组记录各位置左右两侧的最大高度,这导致空间复杂度为O(n)。那么,能否进一步优化空间复杂度至O(1)呢?答案是肯定的。通过观察发现,每个位置的储水量仅由其左右两侧最大高度的较小值决定,而双指针技术可巧妙利用这一特性,用两个变量替代数组存储中间状态。

核心思路:双指针与变量维护

我们引入两个指针left和right,分别指向数组首尾两端,同时用两个变量left_max和right_max动态记录当前左右指针处的历史最大高度。具体逻辑如下:

  1. 初始化:left = 0,right = n-1,left_max = 0,right_max = 0。
  1. 指针移动规则:当height[left] < height[right]时,说明左侧当前高度较低,其储水量由左侧历史最大高度决定。此时计算left位置的储水量,并右移left指针。当height[left] ≥ height[right]时,说明右侧当前高度较低,其储水量由右侧历史最大高度决定。此时计算right位置的储水量,并左移right指针。
  2. 动态更新最大高度:每次处理指针位置前,先更新对应方向的历史最大高度(left_max或right_max)。

具体实现步骤

假设数组长度为n,初始时双指针未相遇(left < right),循环执行以下操作:

  1. 更新历史最大高度
  2. left_max = max(left_max, height[left])
  3. right_max = max(right_max, height[right])
  4. 比较当前指针处高度
  5. height[left] < height[right]
  6. 此时左侧最大高度left_max必然小于等于右侧最大高度right_max(因height[left]是较小值),故left位置的储水量为 left_max - height[left]。
  7. 将该值累加到总储水量,然后left++。
  8. height[left] ≥ height[right]
  9. 此时右侧最大高度right_max必然小于等于左侧最大高度left_max,故right位置的储水量为 right_max - height[right]。
  10. 将该值累加到总储水量,然后right--。
  11. 循环终止条件:当left == right时,遍历结束,返回总储水量。

关键逻辑推导

  • 为什么可以用单变量替代数组?当height[left] < height[right]时,left位置的右侧最大高度至少为height[right](后续right指针左移可能遇到更高高度),但储水量由左右两侧的较小值决定。由于height[left]是当前较小值,其左侧最大高度left_max已确定为左侧全局最大值,因此无需记录右侧所有位置的最大值,只需保证left_max是左侧历史最大值即可。同理适用于右侧情况。

复杂度分析

  • 时间复杂度:O(n),每个元素仅被左右指针各访问一次。
  • 空间复杂度:O(1),仅使用常数级额外空间(指针和变量)。

总结

通过双指针技术,我们避免了存储两个完整数组,将空间复杂度从O(n)优化至O(1),同时保持线性时间复杂度。该解法的核心在于利用左右指针的相对高度关系,动态确定当前位置的储水量由哪一侧的最大高度主导,从而实现空间效率的显著提升。

3.双指针写法代码

class Solution {
public:
    int trap(vector<int>& v) {
        int n=v.size();
        int l=0;
        int r=n-1;
        int ans=0;
        int lmax=0,rmax=0;
        while(l<=r)
        {
            lmax=max(lmax,v[l]);
            rmax=max(rmax,v[r]);
            if(v[r]>=v[l])
            {
                ans+=lmax-v[l];
                l++;
            }
            else 
            {
                ans+=rmax-v[r];
                r--;
            }
        }

        return ans;
    }
};

本题解为参考力扣题解后的总结!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2378947.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

通义千问-langchain使用构建(三)

目录 序言docker 部署xinference1WSL环境docker安装2拉取镜像运行容器3使用的界面 本地跑chatchat1rag踩坑2使用的界面2.1配置个前置条件然后对话2.2rag对话 结论 序言 在前两天的基础上&#xff0c;将xinference调整为wsl环境&#xff0c;docker部署。 然后langchain chatcha…

系统漏洞扫描服务:维护网络安全的关键与服务原理?

系统漏洞扫描服务是维护网络安全的关键措施&#xff0c;能够迅速发现系统中的潜在风险&#xff0c;有效预防可能的风险和损失。面对网络攻击手段的日益复杂化&#xff0c;这一服务的重要性日益显著。 服务原理 系统漏洞扫描服务犹如一名恪尽职守的安全守护者。它运用各类扫描…

【Redis】零碎知识点(易忘 / 易错)总结回顾

一、Redis 是一种基于键值对&#xff08;key-value&#xff09;的 NoSQL 数据库 二、Redis 会将所有数据都存放在内存中&#xff0c;所以它的读写性能非常惊人 Redis 还可以将内存的数据利用快照和日志的形式保存到硬盘上&#xff0c;这样在发生类似断电或者机器故障时&#xf…

基于three.js 全景图片或视频开源库Photo Sphere Viewer

Photo Sphere Viewer 是一个基于 JavaScript 的开源库&#xff0c;专门用于在网页上展示 360 全景图片或视频。它提供了丰富的交互功能&#xff0c;允许用户通过鼠标、触摸屏或陀螺仪来浏览全景内容&#xff0c;适用于旅游、房地产、虚拟现实、教育等多个领域。 主要特点 多种…

LangPDF: Empowering Your PDFs with Intelligent Language Processing

LangPDF: Empowering Your PDFs with Intelligent Language Processing Unlock Global Communication: AI-Powered PDF Translation and Beyond In an interconnected world, seamless multilingual document management is not just an advantage—it’s a necessity. LangP…

OpenVLA (2) 机器人环境和环境数据

文章目录 [TOC](文章目录) 前言1 BridgeData V21.1 概述1.2 硬件环境 2 数据集2.1 场景与结构2.2 数据结构2.2.1 images02.2.2 obs_dict.pkl2.2.3 policy_out.pkl 3 close question3.1 英伟达环境3.2 LIBERO 环境更适合仿真3.3 4090 运行问题 前言 按照笔者之前的行业经验, 数…

代码复现5——VLMaps

项目地址 1 Setup # 拉取VLMaps仓库,成功运行后会在主目录生成文件夹vlmapsgit clone https://github.com/vlmaps/vlmaps.git#通过 conda 创建虚拟环境conda create -n vlmaps python=3.8 -yconda activate vlmaps #激活环境cd vlmaps # 切换到项目文件下bash install.ba…

Ocean: Object-aware Anchor-free Tracking

领域&#xff1a;Object tracking It aims to infer the location of an arbitrary target in a video sequence, given only its location in the first frame 问题/现象&#xff1a; Anchor-based Siamese trackers have achieved remarkable advancements in accuracy, yet…

计算机网络(1)——概述

1.计算机网络基本概念 1.1 什么是计算机网络 计算机网络的产生背景 在计算机网络出现之前&#xff0c;计算机之间都是相互独立的&#xff0c;每台计算机只能访问自身存储的数据&#xff0c;无法与其他计算机进行数据交换和资源共享。这种独立的计算机系统存在诸多局限性&#…

刘家祎双剧收官见证蜕变,诠释多面人生

近期&#xff0c;两部风格迥异的剧集迎来收官时刻&#xff0c;而青年演员刘家祎在《我家的医生》与《无尽的尽头》中的精彩演绎&#xff0c;无疑成为观众热议的焦点。从温暖治愈的医疗日常到冷峻深刻的少年救赎&#xff0c;他以极具张力的表演&#xff0c;展现出令人惊叹的可塑…

Axure制作可视化大屏动态滚动列表教程

在可视化大屏设计中&#xff0c;动态滚动列表是一种常见且实用的展示方式&#xff0c;能够有效地展示大量信息。本文将详细介绍如何使用Axure制作一个动态滚动的列表展示模块。 一、准备工作 打开Axure软件&#xff1a;确保你已经安装并打开了Axure RP软件。创建新项目&#x…

MATLAB实现振幅调制(AM调制信号)

AM调制是通信专业非常重要的一个知识点。今天我们使用MATLAB编程实现AM调制。 我们实现输入一个载波信号的频率与调制信号的频率后&#xff0c;再输入调幅度&#xff0c;得到已调信号的波形与包络信号的波形&#xff0c;再使用FFT算法分析出已调信号的频谱图。 源代码&#x…

6.1.1图的基本概念

基本概念 图&#xff1a; 顶点集边集 顶点集&#xff1a;所有顶点的集合&#xff0c;不能为空&#xff08;因为图是顶点集和边集组成&#xff0c;其中一个顶点集不能为空&#xff0c;则图肯定不为空&#xff09; 边集&#xff1a;所有边的集合&#xff0c;边是由顶点集中的2…

Linux面试题集合(6)

创建多级目录或者同级目录 mkdir -p 文件名/文件名/文件名 mkdir -p 文件名 文件名 文件名 Linux创建一个文件 touch 文件名 DOS命令创建文件 echo 内容>文件名&#xff08;创建一个有内容的文件&#xff09; echo >文件名&#xff08;创建一个没有内容的文件&#xff09…

时间筛掉了不够坚定的东西

2025年5月17日&#xff0c;16~25℃&#xff0c;还好 待办&#xff1a; 《高等数学1》重修考试 《高等数学2》备课 《物理[2]》备课 《高等数学2》取消考试资格学生名单 《物理[2]》取消考试资格名单 职称申报材料 2024年税务申报 5月24日、25日监考报名 遇见&#xff1a;敲了一…

YOLOv7训练时4个类别只出2个类别

正常是4个类别&#xff1a; 但是YOLOv7训练完后预测总是只有两个类别&#xff1a; 而且都是LFM和SFM 我一开始检查了下特征图大小&#xff0c;如果输入是640*640的话&#xff0c;三个尺度特征图是80*80,40*40,20*20&#xff1b;如果输入是416*416的话&#xff0c;三个尺度特征…

【论文阅读】针对BEV感知的攻击

Understanding the Robustness of 3D Object Detection with Bird’s-Eye-View Representations in Autonomous Driving 这篇文章是发表在CVPR上的一篇文章&#xff0c;针对基于BEV的目标检测算法进行了两类可靠性分析&#xff0c;即恶劣自然条件以及敌对攻击。同时也提出了一…

flutter 配置 安卓、Ios启动图

android 配置启动图 launch_background.xml <?xml version"1.0" encoding"utf-8"?> <!-- Modify this file to customize your launch splash screen --> <layer-list xmlns:android"http://schemas.android.com/apk/res/android&…

基于朴素贝叶斯与 LSTM 的假新闻检测模型对比分析

一、引言 在信息爆炸的时代&#xff0c;假新闻的传播对社会产生了诸多负面影响。如何快速、准确地识别假新闻成为了重要的研究课题。本文将对比传统机器学习算法&#xff08;朴素贝叶斯&#xff09;与深度学习模型&#xff08;LSTM&#xff09;在假新闻检测任务中的性能表现&am…

【LeetCode 热题 100】搜索插入位置 / 搜索旋转排序数组 / 寻找旋转排序数组中的最小值

⭐️个人主页&#xff1a;小羊 ⭐️所属专栏&#xff1a;LeetCode 热题 100 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 搜索插入位置搜索二维矩阵在排序数组中查找元素的第一个和最后一个位置搜索旋转排序数组寻找旋转排序数组中的最小值…