leetcode--接雨水(雙指針法,動態規劃,單調棧)

?

目錄

方法一:雙指針法

?方法二:動態規劃

方法三:單調棧




42. 接雨水 - 力扣(LeetCode)

?

黑色的是柱子,藍色的是雨水,我們先來觀察一下雨水的分布情況:
雨水落在凹槽之間,在一個凹槽的左右都會有兩個柱子,兩個柱子高度可能相同也可能不同,柱子的高低決定了凹槽的雨水的高度,雨水的高度等于兩個柱子較低的高度。

方法一:雙指針法

時間復雜度:O(N^2);

空間復雜度:O(1);

缺點:會超時;

思想:統計各個所在位置的左邊最高高度和右邊最高位置(第一個和最后一個柱子所在位置不用統計,他們不可能會接收雨水),然后算出各個位置雨水面積(兩邊的最高高度的較小值 - 當前位置的柱子的面積),最后將各個位置的面積相加得到總面積。

?具體實現:

class Solution {
public:int trap(vector<int>& height) {//面積和int sum = 0;for(int i = 0; i < height.size(); i++){//第一個和最后一個不用統計if(i == 0 || i == height.size() - 1)continue;int maxLeft = height[i];int maxRight = height[i];//統計右邊for(int j = i + 1; j < height.size(); j++){maxRight = max(maxRight,height[j]);}//統計左邊for(int j = i - 1; j >= 0; j--){maxLeft = max(maxLeft,height[j]);}//高度計算int h = min(maxLeft,maxRight) - height[i];if(h > 0)sum += h;}return sum;}
};

?方法二:動態規劃

時間復雜度為 O(N);

空間復雜度為 O(N);

思路:在方法一的基礎上我們知道,只要知道各個位置的左右最高高度,通過計算就可以求得各個位置的面積,再相加就可以得到總面積。所以就需要遍歷數組來找到左右最高高度,方法一使用雙指針來求左右最高高度,每走到柱子位置就向左右方向進行統計,實際上是進行了重復計算的,導致時間復雜度為O(N^2)。因為柱子的位置都不會變,對于每個柱子,相對的左右最高高度也是不會變的,所以只需要遍歷兩次,把每個位置的左右最高高度計算出來放在兩個數組中,最后再計算面積就行了。

class Solution {
public:int trap(vector<int>& height) {//動態規劃做法//小于等于2個直接返回if(height.size() <= 2)return 0;//左邊最高高度--數組初始化為0vector<int> maxLeft(height.size(),0);//右邊最高高度--數組初始化為0vector<int> maxRight(height.size(),0);//遍歷一次數組記錄各個位置的左邊最高高度maxLeft[0] = height[0];for(int i = 1; i < maxLeft.size(); i++){maxLeft[i] = max(height[i],maxLeft[i - 1]);}//遍歷一次數組記錄各個位置的右邊最高高度maxRight[maxRight.size() - 1] = height[height.size() - 1];for(int i = maxRight.size() - 2; i >= 0; i--){maxRight[i] = max(height[i],maxRight[i + 1]);}//求和int sum = 0;for(int i = 0; i < height.size(); i++){int count = min(maxLeft[i],maxRight[i]) - height[i];if(count > 0){sum += count;}}return sum;}
};

方法三:單調棧

空間復雜度:O(n);

時間復雜度:O(n);

使用單調棧使站內元素有序,然而單調棧沒有現成的容器,所以需要我們自己維持元素有序;

那么棧內有序是(棧底->棧頂) 小->大 還是 大->小呢?答案是大->小;當下一個柱子高度小于棧頂元素時就入棧,就能維持棧內有序,當遇到下一個柱子高度大于棧頂元素時就將棧頂pop掉,再將當前的棧頂元素與下一個柱子的高度比較就可以得到較小值,然后就和上面一樣計算面積了。

class Solution {
public:int trap(vector<int>& height) {//如果數組個數兩個及以下,直接returnif(height.size() <= 2)return 0;//創建單調棧(棧頂->棧底==小->大),存放下標值stack<int> st;st.push(0);//統計面積int sum = 0;//行方向計算for(int i = 1; i < height.size(); i++){//1.下一個元素小于棧頂元素if(height[i] < height[st.top()]){st.push(i);}//2.下一個元素等于棧頂元素--pop棧頂元素的下標,push下一個元素的下標else if(height[i] == height[st.top()]){st.pop();st.push(i);}//3.下一個元素大于棧頂元素--形成凹槽接收雨水,計算雨水面積else{while(!st.empty() && height[i] > height[st.top()]){//中間的凹槽下標int mid = st.top();st.pop();if(!st.empty()){//高度計算int h = min(height[st.top()],height[i]) - height[mid];//寬度計算int w = i - st.top() - 1;//面積sum += h * w;}}st.push(i);}}return sum;}
};

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/712879.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/712879.shtml
英文地址,請注明出處:http://en.pswp.cn/news/712879.shtml

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

相關文章

使用js寫一個登錄驗證碼效果

面試題 登錄頁面獲取驗證碼的功能&#xff0c;用戶點擊獲取驗證碼按鈕(id”btn1”)&#xff0c;按文字變為“(N)后獲取驗證碼”&#xff0c;N為倒計對秒數&#xff0c;從 60 開始&#xff0c;每秒減一&#xff0c;減到 0的時候&#xff0c;按鈕文字變為“獲取驗證碼”&#xff…

Beans模塊之工廠模塊Aware

博主介紹:?全網粉絲5W+,全棧開發工程師,從事多年軟件開發,在大廠呆過。持有軟件中級、六級等證書。可提供微服務項目搭建與畢業項目實戰,博主也曾寫過優秀論文,查重率極低,在這方面有豐富的經驗? 博主作品:《Java項目案例》主要基于SpringBoot+MyBatis/MyBatis-plus+…

【JavaWeb】

Javaweb 數據庫相關概念MySQL數據庫MySQL數據模型SQLDDL--操作數據庫圖形化客戶端工具DML--操作數據DQL數據庫約束 數據庫設計多表查詢事務 數據庫相關概念 數據庫 存儲數據的倉庫&#xff0c;數據是有組織的進行存儲 英文&#xff1a;DataBase&#xff0c;簡稱DB 數據庫管理系…

單元測試數據庫回滾問題

問題現象&#xff1a; 在進行單元測試時&#xff0c;測試執行成功&#xff0c;可是數據庫中的數據沒變 問題解決&#xff1a;單元測試自動回滾&#xff0c;需要加上注解Rollback(false) https://zhhll.icu/2020/javaweb/問題/1.單元測試數據問題/ 本文由 mdnice 多平臺發布

機器學習-3

文章目錄 前言訓練驗證測試評估評估方法交叉驗證法自助法評估指標 練習題 前言 本篇介紹機器學習中的訓練、驗證、測試與評估的相關概念。 訓練 從數據中學得模型的過程稱為“學習”(learning)或“訓練”(training),這個過程通過執行某個學習算法來完成.訓練過程中使用的數據…

Android T 遠程動畫顯示流程其三——桌面側動畫啟動到系統側結束流程

前言 接著前文分析Android T 遠程動畫顯示流程其二 我們通過IRemoteAnimationRunner跨進程通信從系統進程來到了桌面進程&#xff0c;這里是真正動畫播放的邏輯。 之后又通過IRemoteAnimationFinishedCallback跨進程通信回到系統進程&#xff0c;處理動畫結束時的邏輯。 進入…

使用maven項目引入jQuery

最近在自學 springBoot &#xff0c;期間準備搞一個前后端不分離的東西&#xff0c;于是需要在 maven 中引入jQuery 依賴&#xff0c;網上百度了很多&#xff0c;這里來做一個總結。 1、pom.xml 導入依賴 打開我們項目的 pom.xml 文件&#xff0c;輸入以下坐標。這里我使用的是…

FPGA-學會使用vivado中的存儲器資源ROM(IP核)

問題&#xff1a; 某芯片,有500個寄存器,需要在上電的時候由FPGA向這些寄存器中寫入初始值,初始值已經通過相應的文檔給出了具體值,這些值都是已知的。 分析關鍵點&#xff1a; 數據量比較多&#xff08;Verilog代碼&#xff0c;通過case語句、always語句這種查找表的方式,數…

Linux——匿名管道

Linux——匿名管道 什么是管道匿名管道的底層原理觀察匿名管道現象讀寫端的幾種情況寫端慢&#xff0c;讀端快寫端快&#xff0c;讀端慢 管道的大小寫端關閉&#xff0c;讀端一直讀寫端一直寫&#xff0c;讀端關閉 我們之前一直用的是vim來編寫代碼&#xff0c;現在有了vscode這…

bert 相似度任務訓練,簡單版本

目錄 任務 代碼 train.py predit.py 數據 任務 使用 bert-base-chinese 訓練相似度任務&#xff0c;參考&#xff1a;微調BERT模型實現相似性判斷 - 知乎 參考他上面代碼&#xff0c;他使用的是 BertForNextSentencePrediction 模型&#xff0c;BertForNextSentencePred…

thinkphp學習10-數據庫的修改刪除

數據修改 使用 update()方法來修改數據&#xff0c;修改成功返回影響行數&#xff0c;沒有修改返回 0 public function index(){$data [username > 孫悟空1,];return Db::name(user)->where(id,11)->update($data);}如果修改數據包含了主鍵信息&#xff0c;比如 i…

STM32標準庫開發——BKP備份RTC時鐘

備份寄存器BKP(Backup Registers) 由于RTC與BKP關聯性較高&#xff0c;所以RTC的時鐘校準寄存器以及一些功能都放在了BKP中。TAMPER引腳主要用于防止芯片數據泄露&#xff0c;可以設計一個機關當TAMPER引腳發生電平跳變時自動清除寄存器內數據不同芯片BKP區別&#xff0c;主要體…

c++入門(2)

上期我們說到了部分c修補C語言的不足&#xff0c;今天我們將剩下的一一說清楚。 函數重載 (1).函數重載的形式 C語言不允許函數名相同的同時存在&#xff0c;但是C允許同名函數存在&#xff0c;但是有要求&#xff1a;函數名相同&#xff0c;參數不同&#xff0c;構成函數重…

【數據結構-圖論】并查集

并查集&#xff08;Union-Find&#xff09;是一種數據結構&#xff0c;它提供了處理一些不交集的合并及查詢問題的高效方法。并查集主要支持兩種操作&#xff1a; 查找&#xff08;Find&#xff09;&#xff1a;確定某個元素屬于哪個子集&#xff0c;這通常意味著找到該子集的…

vue購物車實戰

1.引入vue <script src"https://cdn.jsdelivr.net/npm/vue2.7.14/dist/vue.js"></script> 2.設置高亮部分的樣式 <style> table tr{text-align: center;}.skyblue{background-color: skyblue;}</style> 3.設置body的基本樣式 <div id&q…

人大金倉與mysql的差異與替換

人大金倉中不能使用~下面的符號&#xff0c;字段中使用”&#xff0c;無法識別建表語句 創建表時語句中只定義字段名.字段類型.是否是否為空 Varchar類型改為varchar&#xff08;長度 char&#xff09; Int(0) 類型為int4 定義主鍵&#xff1a;CONSTRAINT 鍵名 主鍵類型&#x…

Found option without preceding group in config file 問題解決

方法就是用記事本打開 然后 左上角點擊 文件 有另存為 就可以選擇編碼格式

Linux設置程序任意位置執行(設置環境變量)

問題 直接編譯出來的可執行程序在執行時需要寫出完整路徑比較麻煩&#xff0c;設置環境變量可以實現在任意位置直接運行。 解決 1.打開.bashrc文件 vim ~/.bashrc 2.修改該文件&#xff08;實現將/home/zhangziheng/file/seqrequester/build/bin&#xff0c;路徑下的可執…

文件流【文件輸入流】

文件流&#xff1a;使用文件輸入流讀取文件中的數據&#xff1a; public class FISDemo {public static void main(String[] args) throws IOException {//將fos.dat文件中的字節讀取回來/*fos.dat文件中的數據:00000001 00000010*/FileInputStream fis new FileInputStream(…

第六節:Vben Admin權限-后端控制方式

系列文章目錄 第一節:Vben Admin介紹和初次運行 第二節:Vben Admin 登錄邏輯梳理和對接后端準備 第三節:Vben Admin登錄對接后端login接口 第四節:Vben Admin登錄對接后端getUserInfo接口 第五節:Vben Admin權限-前端控制方式 文章目錄 系列文章目錄前言一、角色權限(后端…