lc42接雨水

1.原題

42. 接雨水 - 力扣(LeetCode)

給定?n?個非負整數表示每個寬度為?1?的柱子的高度圖,計算按此排列的柱子,下雨之后能接多少雨水。

2.題目解析

這一題是經常被考到的一道算法題,其中最簡單最好用的方法就是雙指針,今天我們就以雙指針的角度來解決這一題!

2.1動態規劃寫法

我們先從動態規劃的角度引入雙指針的視角!

在計算數組height中下標i處接雨水量時,存在這樣一個規律:下雨后水在該位置能達到的最大高度,等同于i兩側高度中的最小值,而i處實際能承接的雨水量,就是這個最大高度減去height[i]的值。

如果采用最基礎的解決方式,針對數組height里的每一個元素,都需要分別朝左、右方向進行掃描,記錄下左右兩邊的最大高度,進而算出每個下標位置能承接的雨水量。若數組height長度為n,由于對每個下標位置進行左右掃描都要耗費O(n)的時間,最終整體的時間復雜度會達到O(n2) 。

這種基礎做法之所以耗時較長,根源在于對每個下標位置都要重復執行左右掃描操作。要是能提前獲取每個位置兩側的最大高度,就能將計算能接雨水總量的時間復雜度降至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.pswp.cn/pingmian/81240.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/81240.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/81240.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【讀代碼】端到端多模態語言模型Ultravox深度解析

一、項目基本介紹 Ultravox是由Fixie AI團隊開發的開源多模態大語言模型,專注于實現音頻-文本的端到端實時交互。項目基于Llama 3、Mistral等開源模型,通過創新的跨模態投影架構,繞過了傳統語音識別(ASR)的中間步驟,可直接將音頻特征映射到語言模型的高維空間。 核心優…

力扣HOT100之二叉樹:98. 驗證二叉搜索樹

這道題之前也刷過&#xff0c;自己做了一遍&#xff0c;發現卡在了第70多個樣例&#xff0c;才發現自己沒有利用二叉搜索樹的性質&#xff0c;但凡涉及到二叉搜索樹&#xff0c;應該首先考慮中序遍歷&#xff01;&#xff01;&#xff01; 被卡住的測試樣例是這樣的&#xff1a…

Centos7.9同步外網yum源至內網

curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo yum makecache yum repolist安裝軟件 yum install -y yum-utils createrepo # yum-utils包含re…

HMDB51數據集劃分

生成訓練集、驗證集和測試集 每個split文件應該包含&#xff1a; 訓練集(id1): 70個視頻測試集(id2): 30個視頻未使用(id0): 剩余視頻 這是一個70/30的訓練/測試分割比例。標記為0的視頻被排除在當前實驗之外。實際上訓練集&#xff08;id1&#xff09;&#xff0c;驗證集&am…

Spring Boot 項目的計算機專業論文參考文獻

技術范圍&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬蟲、數據可視化、小程序、安卓app、大數據、物聯網、機器學習等設計與開發。 主要內容&#xff1a;免費功能設計、開題報告、任務書、中期檢查PPT、系統功能實現、代碼編寫、論文編寫和輔導、論文…

【Linux】Linux安裝并配置MongoDB

目錄 1.添加倉庫 2.安裝 MongoDB 包 3.啟動 MongoDB 服務 4. 驗證安裝 5.配置 5.1.進入無認證模式 5.2.1創建用戶 5.2.2.開啟認證 5.2.3重啟 5.2.4.登錄 6.端口變更 7.卸載 7.1.停止 MongoDB 服務 7.2.禁用 MongoDB 開機自啟動 7.3.卸載 MongoDB 包 7.4.刪除數…

2025/517學習

對離群值怎么操作。這個就是擬合操作的。用更彎曲的曲線去擬合&#xff0c;如常見函數log 多元回歸和單元回歸 如題&#xff0c;如果我有多個自變量&#xff0c;來對一個因變量進行OLS回歸&#xff0c;有沒有operator可以做到&#xff1f;(ts_regression似乎只支持一個…

RKNN開發環境搭建(ubuntu22.04)

以下情況在RV1106G3的平臺上驗證正常。 1、conda安裝 1&#xff09;conda --version//確認是否安裝 2&#xff09;創建一個安裝目錄&#xff0c;進行下一步 3&#xff09;wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-4.6.14-Linux-x…

Flutter到HarmonyOS Next 的跨越:memory_info庫的鴻蒙適配之旅

Flutter到鴻蒙的跨越&#xff1a;memory_info庫的鴻蒙適配之旅 本項目作者&#xff1a;kirk/堅果 您可以使用這個Flutter插件來更改應用程序圖標上的角標 作者倉庫&#xff1a;https://github.com/MrOlolo/memory_info/tree/master/memory_info 在數字化浪潮的推動下&#…

VLAN擴展技術

端口隔離 &#x1f310; 一、原理總結&#xff1a; 端口隔離功能&#xff1a;實現同一VLAN內端口之間的二層隔離。 用戶只需將端口加入同一個隔離組&#xff08;Port-isolate group&#xff09;&#xff0c;即可實現這些端口之間不能互通。 實現效果&#xff1a;更安全、更加…

設計模式 - 單例模式 - Tips

為什么雙重檢查會帶來空指針異常問題&#xff1f; if (instance null) { synchronized (Singleton.class) { if (instance null) { instance new Singleton(); } } …

【Ragflow】22.RagflowPlus(v0.3.0):用戶會話管理/文件類型拓展/諸多優化更新

概述 在歷經三周的階段性開發后&#xff0c;RagflowPlus順利完成既定計劃&#xff0c;正式發布v0.3.0版本。 開源地址&#xff1a;https://github.com/zstar1003/ragflow-plus 新功能 1. 用戶會話管理 在后臺管理系統中&#xff0c;新增用戶會話管理菜單。在此菜單中&…

c++重要知識點匯總(不定期更新)

前言 真心希望各位dalao點贊收藏~ 樹狀數組 作用&#xff1a;高效求出區間前綴和&#xff0c;允許進行修改操作。 舉個栗子&#xff1a; 剛開始有8項&#xff0c;分別為1-8。 首先構建二叉樹&#xff1a; 1-8/ |/ |/ |/ |/ |1-4 5-8/ | / |/ | / |1-…

Predict Podcast Listening Time-(回歸+特征工程+xgb)

Predict Podcast Listening Time 題意&#xff1a; 給你沒個播客的信息&#xff0c;讓你預測觀眾的聆聽時間。 數據處理&#xff1a; 1.構造新特征收聽效率進行分組 2.對數據異常處理 3.對時間情緒等進行數值編碼 4.求某特征值求多項式特征 5.生成特征組合 6.交叉驗證并enc…

Class類的詳細說明

Class類的詳細說明 Class 類是Java反射機制的核心&#xff0c;每個Java類或接口在JVM中都有一個對應的 Class 對象&#xff0c;用于表示該類的元數據&#xff08;如類名、方法、字段、構造器等&#xff09;。以下是其核心知識點&#xff1a; 1. 獲取Class對象的三種方式 方式…

[逆向工程]C++實現DLL注入:原理、實現與防御全解析(二十五)

[逆向工程]C實現DLL注入&#xff1a;原理、實現與防御全解析&#xff08;二十五&#xff09; 引言 DLL注入&#xff08;DLL Injection&#xff09;是Windows系統下實現進程間通信、功能擴展、監控調試的核心技術之一。本文將從原理分析、代碼實現、實戰調試到防御方案&#x…

【ROS2實戰】在中國地區 Ubuntu 22.04 上安裝 ROS 2 Humble 教程

本文介紹如何在中國大陸環境下順利安裝 ROS 2 Humble&#xff0c;包括使用清華鏡像源、解決 locale 和 GPG 密鑰問題、安裝 ROS 軟件包以及配置自動環境加載。 &#x1f31f; ROS 2 版本簡介 ROS 2 是機器人操作系統的第二代版本&#xff0c;目前主要有兩個長期支持&#xff0…

嵌入式學習筆記 - STM32 ADC 模塊工作模式總結

ADC 模式總結&#xff1a; 一 單ADC模式&#xff08;是指ADC1,ADC2,ADC3中只有一個ADC被使用&#xff09; ①單通道&#xff1a; 非連續模式&#xff1a;非連續的意思就是單次&#xff0c;一次轉換完成后就停止轉換&#xff0c;除非再次被軟件或者被外部觸發啟動&#xff1b…

Python訓練打卡Day26

函數專題1&#xff1a;函數定義與參數 知識點回顧&#xff1a; 函數的定義變量作用域&#xff1a;局部變量和全局變量函數的參數類型&#xff1a;位置參數、默認參數、不定參數傳遞參數的手段&#xff1a;關鍵詞參數傳遞參數的順序&#xff1a;同時出現三種參數類型時 到目前為…

使用Docker部署Nacos

sudo systemctl start docker sudo systemctl enable docker docker --version 步驟 2: 拉取 Nacos Docker 鏡像 拉取 Nacos 鏡像&#xff1a; 你可以從 Docker Hub 上拉取官方的 Nacos 鏡像&#xff0c;使用以下命令&#xff1a; docker pull nacos/nacos-server 這會從 …