【力扣題目分享】棧專題(C++)

目錄

關于棧的題目:

1. 最小棧:

?思路:

實現代碼(最終):?

2. 棧的壓入、彈出序列:

思路:

實現代碼:

?3. 逆波蘭表達式求值:

思路:

實現代碼:

深入了解逆波蘭表達式:?

實現代碼:?

用棧實現隊列?

思路:?

實現代碼:


學了棧卻不知道該怎么用于做題?本篇將分享幾道棧相關的經典題目

關于棧的題目:

1. 最小棧:

?思路:

先拿示例一舉例,我們可以定義兩個棧,st和min

st用來存push進去的數據,而min用來存當前st中數據的最小值,具體怎么實現呢?模擬一下示例1

?實現代碼:

class MinStack {
public:/** initialize your data structure here. */MinStack() {//這里可以不用寫,會調用默認的構造函數}void push(int x) {st.push(x);//先入普通的棧if(min.empty() || x<min.top())//如果這個數據小于等于最小棧中棧頂的數據,就插入,讓x成為新的最小值min.push(x);}void pop() {if(st.top() == min.top())//如果要刪除的數和最小棧的棧頂的值相同,就代表要刪除的這個數也是現在棧中最小的數,所以要把最小棧中的那個數也pop掉min.pop();st.pop();}int top() {return st.top();//取普通棧的棧頂}int getMin() {return min.top();//取最小棧的棧頂}
private:stack<int> st;//普通用來存數據的棧stack<int> min;//用來存每一時期的最小值(棧頂就是當前時期的最小值)
};

但如果運行的話會報錯

那我們就用這組出錯的數據再模擬一下

所以在第三步時(即插入第二個0)也應將0入棧min?

這樣即使再getmin,值也還會是0

實現代碼(最終):?

class MinStack {
public:/** initialize your data structure here. */MinStack() {//這里可以不用寫,會調用默認的構造函數}void push(int x) {st.push(x);//先入普通的棧if(min.empty() || x<min.top())//如果這個數據小于等于最小棧中棧頂的數據,就插入,讓x成為新的最小值min.push(x);}void pop() {if(st.top() == min.top())//如果要刪除的數和最小棧的棧頂的值相同,就代表要刪除的這個數也是現在棧中最小的數,所以要把最小棧中的那個數也pop掉min.pop();st.pop();}int top() {return st.top();//取普通棧的棧頂}int getMin() {return min.top();//取最小棧的棧頂}
private:stack<int> st;//普通用來存數據的棧stack<int> min;//用來存每一時期的最小值(棧頂就是當前時期的最小值)
};

2. 棧的壓入、彈出序列:

思路:

?先定義一個棧,用來模擬入棧出棧

?到下一次入棧時,此時st.pop() == pop[i],所以就要開始出棧,直到st.pop() != pop[i]為止

出棧4后,現在的數據是這樣?

所以要繼續入棧

?刪除完最后一個數據之后

實現代碼:

bool IsPopOrder(vector<int>& pushV, vector<int>& popV) 
{stack<int> st;//創建一個棧,用來存pushV的數據int popi = 0;//popV的進度for(int i=0;i<pushV.size();i++)//每次都入棧pushV的數據{st.push(pushV[i]);while(!st.empty() && st.top() == popV[popi])//如果現在棧頂的數據等于popV進度的數據,就表示需要開始出棧了{st.pop();popi++;}}return st.empty();//如果最后棧里沒有數據了,就代表全pop完了,就是對的
}

?3. 逆波蘭表達式求值:

思路:

逆波蘭表達式,也叫后綴表達式,我們平常用的表達式是中綴表達式,例如a+b,寫成后綴表達式就是ab+,即把操作符放到了數的后面,這是為了優先級的區分(更便于計算),優先級越高的操作符就會越在前面

(a+b)*c-(a+b)/e轉換成后綴表達式就是ab+c*ab+e/-,即先讓"a"和"b"執行"+"操作,然后讓"a+b"的值和"c"執行"*"操作,再讓"a"和"b"執行"+"操作,以此類推

?相信對棧有一定了解的人都已經想到了,這道題可以用棧模擬的方法輕松解決

遇到非操作符就入棧,遇到操作符就把棧的前兩個元素出棧并運算,運算完把結果再入棧就可以

?具體點來說,拿示例1模擬

示例二模擬:

?

可以看到,最后存在棧(棧頂)的數據就是最終結果

實現代碼:

int evalRPN(vector<string>& tokens) 
{stack<int> st;//用一個棧來模擬數運算的先后順序int i=0;while(i < tokens.size())//遍歷數組{if(tokens[i] != "+" && tokens[i] != "-" && tokens[i] != "*" && tokens[i] != "/")//如果不是算數符就入棧st.push(stoi(tokens[i]));else//遇到算數符,就把棧的前兩個元素提出來(第一個提出來的是右元素,第二個是左元素){int right = st.top();st.pop();int left = st.top();st.pop();switch(tokens[i][0])//判斷是哪個算術符{case '+':st.push(left+right); break;case '-':st.push(left-right); break;case '*':st.push(left*right); break;case '/':st.push(left/right); break;}}i++;}return st.top();
}

深入了解逆波蘭表達式:?

注:面試時一般不會考的這么深入,如果有興趣可以看看這部分內容

本題中給出的輸入就已經是逆波蘭表達式了,那中綴表達式是如何轉換成逆波蘭表達式(后綴表達式)的呢

例如,我們有一個中綴表達式1+2*4+3,根據優先級,它會先算2*4,再拿2*4的結果去算另外兩個加式,但如果直接這樣計算的話,不避免的會先算加法式,所以要給它轉換成后綴表達式后用棧的特性來計算

轉換成后綴表達式也需要用棧,下面來模擬一下過程

規則:

  1. 遇到數字,提出來(尾插到后綴表達式中)
  2. 遇到操作符,若此時棧為空,就入棧
  3. 遇到操作符,若此時棧不為空,如果當前操作符比棧頂的操作符優先級要高,就入棧
  4. 遇到操作符,若此時棧不為空,如果當前操作符比棧頂的操作符優先級要低或相等,就出棧掉相等的操作符(直到棧頂為空或比棧頂的優先級要低),并將出棧的操作符尾插到后綴表達式中,然后再入棧新操作符

實現代碼:?
#include <iostream>
#include <string>
#include <vector>
#include <stack>
using namespace std;bool op(string s)//判斷是否為操作符
{if(s=="+"||s=="-"||s=="*"||s=="/")return true;elsereturn false;
}int priority(string s)//返回該操作符的優先級比
{if(s == "+" || s == "-")return 1;else return 2;
}
int main()
{vector<string> infix = {"1","+","2","*","4","+","3"};//待轉換的中綴表達式vector<string> postfix;//待尾插的后綴表達式stack<string> st;//存操作符的棧for(int i=0;i<infix.size();i++){if(op(infix[i]))//如果該位置是操作符{if(st.empty() || priority(st.top()) < priority(infix[i]))//如果棧為空或者棧頂的優先級比當前操作符低,則直接入棧{st.push(infix[i]);}else//否則棧頂的優先級比當前操作符高或相等,則將棧頂的操作符彈出,直到棧頂的優先級比當前操作符低,然后將當前操作符入棧{while(!st.empty() && priority(st.top()) >= priority(infix[i])){string s = st.top();st.pop();postfix.push_back(s);}st.push(infix[i]);}}else//如果該位置是操作數,則直接尾插到后綴表達式中{postfix.push_back(infix[i]);}}while(!st.empty())//將棧中剩余的操作符彈出并尾插到后綴表達式中{string s = st.top();st.pop();postfix.push_back(s);}for(const auto& s : postfix){cout << s << " ";}return 0;
}

輸出結果:

用棧實現隊列?

思路:?

?眾所周知,棧是后進先出(LIFO),而隊列是先進先出(FIFO),想用兩個棧實現先進先出,可以用一個棧專門入數據,另外一個棧專門出數據

拿這個數據來舉例,現在我們要出隊的話,會先出1,怎么樣才能先讀到1呢?

再把數據全部都入到另外一個棧上,此時出棧的順序就和出隊一樣了

當然,還有很多細節沒有處理

只要要出棧時才會用到popst,所以只有要出棧時,才需要把pushst中的數據都入到popst中

并且,當popst中有數據時,就先不用把pushst中的數據入到popst,因為此時如果再入的話popst棧頂的數據就不是先進的那個數了

實現代碼:

class MyQueue {
public:MyQueue() {//讓它調用默認的構造函數就行(stack的構造函數)}void push(int x) {//往pushst中插入數據pushst.push(x);}//先在pushst中插入數據,這樣再一個個出棧到popst時,再popst.top()就是隊尾的數據了int pop() {if(popst.empty())//如果此時popst還是空的,就得先給popst數據{while(!pushst.empty()){int tmp = pushst.top();pushst.pop();popst.push(tmp);}}int x = popst.top();popst.pop();return x;}int peek() {if(popst.empty())//如果此時popst中沒有數據,就要先把pushst的數據給popst{while(!pushst.empty()){int tmp = pushst.top();pushst.pop();popst.push(tmp);}}return popst.top();}bool empty() {//只有兩個棧里都沒有數據才是真沒數據return pushst.empty() && popst.empty();}
private:stack<int> pushst;//負責入棧stack<int> popst;//負責出棧
};

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

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

相關文章

Office 2019 (含Visio+Project)官方IOS 下載

Microsoft Office 2019 是微軟公司推出的一款辦公軟件套裝&#xff0c; 主要包括Word、Excel、PowerPoint、Outlook、Visio、Access、Publisher、OneDrive for Business 和Skype for Business等組件。 這些組件適用于Windows和MacOS平臺&#xff0c;支持多種語言&#xff0c…

遙測終端機,推動灌區流量監測向數據驅動躍遷

灌區范圍那么大&#xff0c;每一滴水怎么流都關系到糧食夠不夠吃&#xff0c;還有生態能不能平衡。過去靠人工巡查、測量&#xff0c;就像拿著算盤想算明白大數據&#xff0c;根本滿足不了現在水利管理的高要求。遙測終端機一出現&#xff0c;就像給灌區流量監測安上了智能感知…

P4017 最大食物鏈計數-拓撲排序

P4017 最大食物鏈計數 題目來源-洛谷 題意 要求最長食物鏈的數量。按照題意&#xff0c;最長食物鏈就是指有向無環圖DAG中入度為&#xff10;到出度為&#xff10;的不同路徑的數量&#xff08;鏈數&#xff09; 思路 在計算時&#xff0c;明顯&#xff1a;一個被捕食者所…

Xmind快捷鍵大全

常規 插入主題和元素&#xff08;常用&#xff09; 編輯主題文本和樣式 選擇和移動 調整畫布和視圖 工具和其他

四. 以Annoy算法建樹的方式聚類清洗圖像數據集,一次建樹,無限次聚類搜索,提升聚類搜索效率。(附完整代碼)

文章內容結構&#xff1a; 一. 先介紹什么是Annoy算法。 二. 用Annoy算法建樹的完整代碼。 三. 用Annoy建樹后的樹特征匹配聚類歸類圖像。 一. 先介紹什么是Annoy算法 下面的文章鏈接將Annoy算法講解的很詳細&#xff0c;這里就不再做過多原理的分析了&#xff0c;想詳細了解…

什么是電容?

什么是電容&#xff1f; 電荷與電壓的比值就是電容量C。電容單位為法拉(F)。1法拉電容器在電壓為1V時儲存的電荷量為1庫倫(C)。圖1.1中的球體表面電壓與儲存的電荷Q關聯。電壓V等于。Q/V等于。如果球體位于電介質媒介中&#xff0c;電壓V降低倍&#xff0c;Q/V等于。在電介質媒…

Linux服務器上mysql8.0+數據庫優化

1.配置文件路徑 /etc/my.cnf # CentOS/RHEL /etc/mysql/my.cnf # Debian/Ubuntu /etc/mysql/mysql.conf.d/mysqld.cnf # Ubuntu/Debian檢查當前配置文件 sudo grep -v "^#" /etc/mysql/mysql.conf.d/mysqld.cnf | grep -v "^$&q…

MQTT學習資源

MQTT入門&#xff1a;強烈推薦

第十二章 Python語言-大數據分析PySpark(終)

目錄 一. PySpark前言介紹 二.基礎準備 三.數據輸入 四.數據計算 1.數據計算-map方法 2.數據計算-flatMap算子 3.數據計算-reduceByKey方法 4.數據計算-filter方法 5.數據計算-distinct方法 6.數據計算-sortBy方法 五.數據輸出 1.輸出Python對象 &#xff08;1&am…

【XR手柄交互】Unity 中使用 InputActions 實現手柄控制詳解(基于 OpenXR + Unity新輸入系統(Input Actions))

摘要&#xff1a; 本文主要介紹如何使用 Input Actions&#xff08;Unity 新輸入系統&#xff09; OpenXR 來實現 VR手柄控制&#xff08;監聽ABXY按鈕、搖桿、抓握等操作&#xff09;。 &#x1f3ae; Unity 中使用 InputActions 實現手柄控制詳解&#xff08;基于 OpenXR 新…

java實現網格交易回測

以下是一個基于Java實現的簡單網格交易回測程序框架&#xff0c;以證券ETF&#xff08;512880&#xff09;為例。代碼包含歷史數據加載、網格策略邏輯和基礎統計指標&#xff1a; import java.io.BufferedReader; import java.io.FileReader; import java.text.ParseException…

探秘 3D 展廳之卓越優勢,解鎖沉浸式體驗新境界

&#xff08;一&#xff09;打破時空枷鎖&#xff0c;全球觸達? 3D 展廳的首要優勢便是打破了時空限制。在傳統展廳中&#xff0c;觀眾需要親臨現場&#xff0c;且必須在展廳開放的特定時間內參觀。而 3D 展廳依托互聯網&#xff0c;讓觀眾無論身處世界哪個角落&#xff0c;只…

第十二屆藍橋杯 2021 C/C++組 直線

目錄 題目&#xff1a; 題目描述&#xff1a; 題目鏈接&#xff1a; 思路&#xff1a; 核心思路&#xff1a; 兩點確定一條直線&#xff1a; 思路詳解&#xff1a; 代碼&#xff1a; 第一種方式代碼詳解&#xff1a; 第二種方式代碼詳解&#xff1a; 題目&#xff1a;…

微信小程序藍牙連接打印機打印單據完整Demo【藍牙小票打印】

文章目錄 一、準備工作1. 硬件準備2. 開發環境 二、小程序配置1. 修改app.json 三、完整代碼實現1. pages/index/index.wxml2. pages/index/index.wxss3. pages/index/index.js 四、ESC/POS指令說明五、測試流程六、常見問題解決七、進一步優化建議 下面我將提供一個完整的微信…

ubuntu opencv 安裝

1.ubuntu opencv 安裝 在Ubuntu系統中安裝OpenCV&#xff0c;可以通過多種方式進行&#xff0c;以下是一種常用的安裝方法&#xff0c;包括從源代碼編譯安裝。請注意&#xff0c;安裝步驟可能會因OpenCV的版本和Ubuntu系統的具體版本而略有不同。 一、安裝準備 更新系統&…

【C++】class靜態常量

Usage: static const T 1 background static const成員屬于類&#xff0c;而不是類的實例&#xff0c;所以它們的初始化需要在類外進行(或者在C17之后可以用inline初始化)。 使用中可能遇到的情況&#xff1a; 在頭文件中聲明一個static const成員&#xff0c;然后在多個cpp…

Java 安全:如何防止 DDoS 攻擊?

一、DDoS 攻擊簡介 DDoS&#xff08;分布式拒絕服務&#xff09;攻擊是一種常見的網絡攻擊手段&#xff0c;攻擊者通過控制大量的僵尸主機向目標服務器發送海量請求&#xff0c;致使服務器資源耗盡&#xff0c;無法正常響應合法用戶請求。在 Java 應用開發中&#xff0c;了解 …

統計文件中單詞出現的次數并累計

# 統計單詞出現次數 fileopen("E:\Dasktape/python_test.txt","r",encoding"UTF-8") f1file.read() # 讀取文件 countf1.count("is") # 統計文件中is 單詞出現的次數 print(f"此文件中單詞is出現了{count}次")# 2.判斷單詞出…

C語言實現貪心算法

一、貪心算法核心思想 特征&#xff1a;在每一步選擇中都采取當前狀態下最優&#xff08;局部最優&#xff09;的選擇&#xff0c;從而希望導致全局最優解 適用場景&#xff1a;需要滿足貪心選擇性質和最優子結構性質 二、經典貪心算法示例 1. 活動選擇問題 目標&#xff1a…

《一文讀懂Transformers庫:開啟自然語言處理新世界的大門》

《一文讀懂Transformers庫:開啟自然語言處理新世界的大門》 GitHub - huggingface/transformers: ?? Transformers: State-of-the-art Machine Learning for Pytorch, TensorFlow, and JAX. HF-Mirror Hello! Transformers快速入門 pip install transformers -i https:/…