單調棧學習C++

目錄

一,每日溫度

二,下一個更大的元素I

三,下一個更大的元素II

四,接雨水

小結:


?單調棧是一種特殊的棧結構,里面的元素按照單調遞增或者遞減的順序排列。常用于解決元素左邊或者右邊比它大或者小的問題。

一,每日溫度

題目鏈接:739. 每日溫度 - 力扣(LeetCode)

【題目描述】

?對于給定的一個temperatures數組,每個元素表示當天的溫度。對于每天的溫度,求出下一次更高的溫度出現在幾天后。

【算法】單調棧

我們可以維護一個棧結構,先將數組的首元素入棧,然后開始遍歷這個數組,如果遍歷到的數組元素比棧頂元素小,那么就入棧;如果相等,也入棧;當遍歷到的數組元素比此時棧頂的元素大時,記錄此時相隔的天數,然后將棧頂元素彈出,繼續比較棧頂的元素和數組元素的大小,直到棧頂元素小于或者等于棧頂元素,此時將該數組元素入棧。然后接著遍歷下一個數組元素,依次循環。

由于題目中求的是相隔的天數,所以我們不需要將數組元素入棧,只需入棧該元素的下標即可,這樣就可以直接計算相隔的天數:數組元素對應的下標減去棧頂元素對應的下標,就是該棧頂元素與下一個更高溫度相隔的天數。?

圖示:(以題目中的示例1為例)

可以發現,棧中的元素(下標對應的元素)始終保持單調遞減(從棧底到棧頂),因此成為單調棧。?

【代碼】

class Solution {
public:vector<int> dailyTemperatures(vector<int>& temperatures) {int n=temperatures.size();vector<int> ans(n,0);stack<int> st;//存儲下標st.push(0);for(int i=1;i<n;i++){//遇到溫度大于棧頂的,就一直出棧,保持遞減性while(!st.empty()&&temperatures[st.top()]<temperatures[i]){int index=st.top();st.pop();ans[index]=i-index;}st.push(i);}return ans;}
};

時間復雜度O(N),每個元素最多入棧依次。空間復雜度O(N)?

二,下一個更大的元素I

題目鏈接:496. 下一個更大元素 I - 力扣(LeetCode)

【題目描述】

本題存在兩個數組,nums1是nums2的子集,對于nums1數組的每個元素,求出這些元素在對應nums2數組中的下一個更大的元素。如果不存在,則為-1

【算法】單調棧

本題與上一題的思路一樣,只不過加了一點要求。

求當前元素的下一個更大的元素,就需要維護一個單調棧(單調遞減)。

本題還是求數組nums2上每個元素的下一個更大的元素是多少。所以還是在nums2數組上使用單調棧。和上題的過程一樣,只不過在判斷的時候,還需加上一個條件。

假設找到了當前棧頂的下一個更大元素k,還需判斷棧頂元素是否在nums1中出現過,如果該元素在nums1中出現過,那么就將k記錄在最終結果數組ans中,不過還需要保證和nums1數組的位置一一對應。

所以可以做下預處理工作,將數組nums1中的元素和下標使用哈希表保存起來。

初始化ans數組時,可以全部初始化為-1.

【代碼】

class Solution {
public:vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {int n=nums1.size();vector<int> ans(n,-1);unordered_map<int,int> hash;for(int i=0;i<n;i++)hash[nums1[i]]=i;stack<int> st;//單調遞減st.push(0);for(int i=1;i<nums2.size();i++){while(!st.empty()&&nums2[st.top()]<nums2[i]){//判斷是否在nums1中出現過if(hash.count(nums2[st.top()])>0){//求出該元素在nums1中對應的下標int index=hash[nums2[st.top()]];//記錄結果ans[index]=nums2[i];}st.pop();}st.push(i);}return ans;}
};

三,下一個更大的元素II

題目鏈接:503. 下一個更大元素 II - 力扣(LeetCode)

【題目描述】

?求一個數組nums每一個元素的下一個更大的數,該數組是循環數組,數組最后一個元素接下來的元素就是數組的第一個元素。

【算法】單調棧

求下一個更大的元素,單調棧(單調遞減棧)。

大致的方向還是使用單調棧。本題的重點是:如何處理循環數組。

方法一:是將原數組nums在后面再拼接一份。然后使用單調棧求下一個更大的元素。

將兩個nums數組拼接起來,使用單調棧求出每一個元素的下一個更大值,存儲在ans數組中,然后將ans數組的大小減為一半。

class Solution {
public:vector<int> nextGreaterElements(vector<int>& nums) {//拼接兩個數組vector<int> nums1(nums.begin(),nums.end());nums.insert(nums.begin(),nums1.begin(),nums1.end());vector<int> ans(nums.size(),-1);stack<int> st;//單調遞減st.push(0);for(int i=1;i<nums.size();i++){while(!st.empty()&&nums[st.top()]<nums[i]){ans[st.top()]=nums[i];st.pop();}st.push(i);}//將數組減為原來的一般ans.resize(nums.size()/2);return ans;}
};

方法二:也可以不用擴充數組,在遍歷的時候模擬走兩邊nums即可。

class Solution {
public:vector<int> nextGreaterElements(vector<int>& nums) {int n=nums.size();vector<int> ans(n,-1);stack<int> st;//單調遞減st.push(0);//模擬走兩邊nums//當遍歷完最后一個元素,執行++后,再取模n,會回到數組的開始for(int i=1;i<2*n;i++){while(!st.empty()&&nums[st.top()]<nums[i%n]){ans[st.top()]=nums[i%n];st.pop();}st.push(i%n);}return ans;}
};

四,接雨水

題目鏈接:42. 接雨水 - 力扣(LeetCode)

【解法一】雙指針?

求這些柱子中一共有多少雨水。看每個柱子可以"接"多少雨水。

也就是統計每個柱子上有多少水,然后將每個柱子上的水加起來即可。

問題是如何求每個柱子上有多少水?

對于第i個柱子,求第i個柱子上有多少水,需要求出第i個柱子左邊柱子最高的高度,以及第i個柱子右邊柱子最高的高度,取兩者的最小值,然后再減去當前柱子的高度。

【代碼】

class Solution {
public:int trap(vector<int>& height) {//雙指針int n=height.size();vector<int> maxLeft(n,0);auto maxRight=maxLeft;//記錄左邊最大值maxLeft[0]=height[0];for(int i=1;i<n;i++)maxLeft[i]=max(maxLeft[i-1],height[i]);//記錄右邊最大值maxRight[n-1]=height[n-1];for(int i=n-2;i>=0;i--)maxRight[i]=max(maxRight[i+1],height[i]);int ans=0;for(int i=0;i<n;i++){int count=min(maxLeft[i],maxRight[i])-height[i];if(count>0) ans+=count;}return ans;}
};

【解法二】單調隊列

這種思路是求柱子與柱子之間的雨水量。

首先需要明白,當后一個柱子高度大于前一個柱子高度,那么一定是會有雨水的。

所以我們需要求下一個更大的元素,使用單調遞減棧。

思路,與前面題的思路一致。


當遍歷到的元素大于棧頂元素時:

此時的棧頂就是下圖的中間柱子,下標記為mid,對應的高度為height[mid],將棧頂元素彈出。

此時的棧頂元素st.top(),就是最左邊的柱子,對應的高度為height[st.top()]。

此時遍歷到的元素是最右邊的柱子,下標為i,柱子高度為height[i]。

最后只需計算出中間雨水的長和寬然后相乘即可。

h=min(height[st.top()],height[i])-height[mid]

w=i-st.top()-1

【代碼】

class Solution {
public:int trap(vector<int>& height) {int n=height.size();int ans=0;stack<int> st;//單調遞減st.push(0);for(int i=1;i<n;i++){while(!st.empty()&&height[st.top()]<height[i]){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;ans+=h*w;}}st.push(i);}return ans;}
};

小結:

單調棧常用于解決元素左側或者右側第一個更大后者更小的問題。

核心原理:

  • 單調遞增棧:棧內元素從棧底到棧頂遞增,用于尋找更小的元素。

  • 單調遞減棧:棧內元素從棧底到棧頂遞減,用于尋找更大的元素。

  • 遍歷數組時,若當前元素破壞單調性,則彈出棧頂元素,直到滿足單調性。

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

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

相關文章

網絡釣魚攻擊的威脅和執法部門的作用(第一部分)

在當今的數字世界中&#xff0c;網絡犯罪分子不斷開發新技術來利用個人、企業和政府機構。 最普遍和最具破壞性的網絡犯罪形式之一是網絡釣魚——一種社會工程手段&#xff0c;用于欺騙人們提供敏感信息&#xff0c;例如登錄憑據、財務數據和個人詳細信息。 隨著網絡釣魚攻擊…

左值與右值,空間與數據

左值是空間&#xff0c;右值是數據 編程總是對“數據”&#xff0c;對"存放數據的空間"操作 a返回一個當前的數據&#xff0c;存放到一個臨時空間中&#xff0c;自身的空間中的數據再進行運算 a直接對自身空間中的數據進行運算 其余知識&#xff1a; 1.變量名的意…

無人機飛行術語科普!

一、基礎操作類 1. 炸機 指無人機意外墜毀或嚴重損壞&#xff08;如撞樹、撞樓、失控摔機等&#xff09;。 例句&#xff1a;“今天風太大&#xff0c;差點炸機&#xff01;” 2. 一鍵放生 調侃某些情況下無人機失控飛丟&#xff0c;無法找回&#xff08;源自某些品牌…

模擬算法(一):一維數組模擬

目錄 模擬的概念 例1&#xff1a;開關燈 算法思路&#xff1a; 代碼如下&#xff1a; 輸入輸出&#xff1a; 例2&#xff1a;序列操作和查詢 算法思路&#xff1a; 代碼如下&#xff1a; 輸入輸出&#xff1a; 例3&#xff1a;數組折疊 算法思路&#xff1a; 代碼如…

MySQL 基礎入門

寫在前面 關于MySQL的下載安裝和其圖形化軟件Navicat的下載安裝,網上已經有了很多的教程,這里就不再贅述了,本文主要是介紹了關于MySQL數據庫的基礎知識。 MySQL數據庫 MySQL數據庫基礎 MySQL數據庫概念 MySQL 數據庫&#xff1a; 是一個關系型數據庫管理系統 。 支持SQL語…

Qt中的多種輸出方式,信號與槽的基本使用

完成Hello World可以通過很多控件實現 如采用編輯框來完成hello world 編輯框分為單行編輯框----QLineEdit 和多行編輯框---QTextEdit 采用單行編輯框&#xff0c;創建項目后&#xff0c;展開forms文件夾&#xff0c;雙擊ui文件進入 qt designer設計頁面 找到line edit 拖到頁…

英語表達年代和世紀

英語表達年代和世紀 1. Century (世紀)1.1. Start and end of centuries 2. Decade (年代)2.1. Usage 3. 英語表達年代和世紀4. HomeworkReferences XXX0 年代指 XXX0 年 - XXX9 年的連續 10 年&#xff0c;例如 1760 年代指 1760 年至 1769 年這連續 10 年。 XX 世紀 X0 年代…

MySQL數據庫管理5

23.事務 1&#xff09;事務&#xff1a;可以認為是做一件事情 需要多個SQL 要么同時成功 要么同時失敗 需求&#xff1a;銀行轉賬update 你的賬戶 把你的錢減少update 你朋友的賬戶 把他的錢增多?這兩個SQL不能只成功一個 要么都成功 要么都失敗那么 我們就需要用到事務了 它…

閉包和裝飾器

什么是閉包 閉包&#xff08;Closure&#xff09;是 Python 中一個非常重要的概念&#xff0c;它是一種特殊的函數對象&#xff0c;通常用于封裝和延遲計算某些值。以下是閉包的詳細定義和解釋&#xff1a; 1.閉包的定義 閉包是指一個函數對象&#xff0c;它不僅包含函數的代…

notepad++8.6.4安裝及細節

notepad8.6.4下載安裝&#xff08;附安裝包&#xff09; 一、安裝包下載1.1方法一&#xff1a;官網下載&#xff08;點擊跳轉&#xff09;1.2方法二&#xff1a;網盤鏈接分享8.6.4版本 二、安裝過程細節2.1這里的組件建議全部勾選。點擊“下一步”。2.2 勾選①&#xff1a;可以…

COZE通關指南:工作流與插件開發

前言 本文隸屬于專欄《AI Agent 通關指南》,該專欄為筆者原創,引用請注明來源,不足和錯誤之處請在評論區幫忙指出,謝謝! 本專欄目錄結構和參考文獻請見《AI Agent 通關指南》 正文 1. 平臺基礎介紹 ?? 1.1 COZE平臺概述 COZE平臺(coze.cn)是一個強大的AI應用開發平臺…

【Block總結】ENLTransformerBlock,高效非局部變換器塊|即插即用

1. 論文信息 標題: Perspective+ Unet: Enhancing Segmentation with Bi-Path Fusion and Efficient Non-Local Attention for Superior Receptive Fields論文地址: arXiv:2406.14052 2. 創新點 雙路徑編碼策略: 在編碼器階段引入雙路徑策略,結合傳統卷積和空洞卷積的結果,平…

【爬蟲】網易云音樂評論數據爬取

文章目錄 &#x1f356; 前言&#x1f3b6;一、抓取要求?二、代碼展示&#x1f3c0;三、運行結果&#x1f3c6;四、知識點提示 &#x1f356; 前言 【爬蟲】網易云音樂歌詞/評論數據爬取 &#x1f3b6;一、抓取要求 描述: 輸入歌曲的id&#xff0c;獲取對應歌曲的用戶評論信…

C++使用Qt Charts創建數據可視化圖表

Qt Charts 是一個強大的工具&#xff0c;用于創建直觀的數據可視化圖表。本文將通過一個具體的示例&#xff0c;展示如何使用 Qt Charts 創建一個包含多條數據序列、自定義坐標軸和隨機數據生成的圖表。 示例代碼解析 以下是一個完整的示例代碼&#xff0c;展示如何使用 Qt Ch…

TCP/IP五層協議

目錄 1. 五層模型結構 2. 各層核心功能與協議 (1) 應用層&#xff08;Application Layer&#xff09; (2) 傳輸層&#xff08;Transport Layer&#xff09; (3) 網絡層&#xff08;Network Layer&#xff09; (4) 數據鏈路層&#xff08;Data Link Layer&#xff09; (5…

【最新版】金媒婚戀系統v10.5最新穩定開源+原生前端小程序 PC端+安裝教程

一.系統簡介 1. 紅娘服務 紅娘服務模塊是該系統的一大特色。專業紅娘會通過分析用戶的個人資料和偏好&#xff0c; 為用戶提供精準的配對建議和個性化服務。用戶可以預約紅娘服務&#xff0c;通過紅娘的介入&#xff0c;提升配對成功率。 2. 相親活動 相親活動模塊用于組織和管…

吳恩達深度學習復盤(5)神經網絡的前向傳播TesorFlow與NumPy實現比對

數據結構差別 NumPy 和 TensorFlow 在數據表示上的差異展開&#xff0c;結合神經網絡實踐中的常見問題進行說明。以下是詳細解析&#xff1a; 一、簡介 數據表示的歷史背景 NumPy 是 Python 科學計算的基礎庫&#xff0c;早期設計為處理多維數組TensorFlow 由 Google Brain 團…

多元高斯分布函數

1、 n n n元向量 假設 n n n元隨機變量 X X X X [ X 1 , X 2 , ? , X i , ? , X n ] T μ [ μ 1 , μ 2 , ? , μ i , ? , μ n ] T σ [ σ 1 , σ 2 , ? , σ i , ? , σ n ] T X i ~ N ( μ i , σ i 2 ) \begin{split} X&[X_1,X_2,\cdots,X_i,\cdots ,X_n…

洞察 Linux 進程管理

一、進程和線程的概念 1.進程 &#xff08;1&#xff09;概念 進程是程序在操作系統中的一次執行過程&#xff0c;是系統進行資源分配和調度的基本單位。進程是程序的執行實例&#xff0c;擁有獨立的資源&#xff08;如內存、文件描述符等&#xff09;。每個進程在創建時會被…

PyTorch 實現圖像版多頭注意力(Multi-Head Attention)和自注意力(Self-Attention)

本文提供一個適用于圖像輸入的多頭注意力機制&#xff08;Multi-Head Attention&#xff09;PyTorch 實現&#xff0c;適用于 ViT、MAE 等視覺 Transformer 中的注意力計算。 模塊說明 輸入支持圖像格式 (B, C, H, W)內部轉換為序列 (B, N, C)&#xff0c;其中 N H * W多頭注…