算法訓練之棧


???~~~~~~歡迎光臨知星小度博客空間~~~~~~???

???零星地變得優秀~也能拼湊出星河~???

???我們一起努力成為更好的自己~???

???如果這一篇博客對你有幫助~別忘了點贊分享哦~???

???如果有什么問題可以評論區留言或者私信我哦~???

??????個人主頁??????

? ? ? ? 這一篇博客我們來探討一下有關于棧的算法練習題,準備好了嗎~我們發車去探索算法的奧秘啦~🚗🚗🚗🚗🚗🚗

目錄

前言😁

刪除字符串中所有相鄰重復項🙃

比較含退格的字符串😜

基本計算器Ⅱ😀

字符串解碼😍

驗證棧序列😝


前言😁

? ? ? ? 我們先來簡單復習一下棧這個數據結構,棧(Stack)是一種后進先出的數據結構,我們可以想象一疊盤子:你通常會把新洗好的盤子放在最上面入棧),而當你需要用一個盤子時,你會從最上面拿走一個(出棧),你無法直接從中間或底部抽出一個盤子,棧的工作原理正是如此。

? ? ? ? 話不多說,我們上題~

刪除字符串中所有相鄰重復項🙃

刪除字符串中所有相鄰重復項

? ? ? ? 看這題目有點眼熟,既然要刪除重復字符,我們就得記錄前面一個字符判斷是否重復,這也就使用到我們強大的數據結構——棧。

算法思路棧模擬過程

①創建一個空棧

②遍歷字符串,如果棧不為空并且棧頂元素與當前字符相等,那么棧頂元素出棧;否則,當前字符入棧

③棧中剩余字符出棧保存到字符串中

代碼實現

//刪除字符串中所有相鄰重復項
class Solution
{
public:string removeDuplicates(string s){//使用數據結構容器——棧stack<char> st;//遍歷字符串for (auto& e : s){//如果棧不為空并且棧頂元素與當前字符相等,那么棧頂元素出棧if (st.size() && e == st.top()){st.pop();}//否則,當前字符入棧(包括空棧的情況)else{st.push(e);}}string ret;//保存返回結果while (!st.empty()){ret += st.top();st.pop();}//逆序字符串就是正確結果reverse(ret.begin(), ret.end());return ret;}
};

順利通過~不過這里的代碼看起來還是有一些繁瑣,我們有沒有什么辦法優化一下,主要在于棧中保存的僅僅是字符,需要進行提取才能得到我們的答案,那我們可以與字符串聯系起來~

優化思路:因為要返回的是字符串,我們可以使用字符串來模擬棧工作的過程,字符串最后一個位置也就是我們的棧頂~

代碼實現

class Solution
{
public:string removeDuplicates(string s){//字符串模擬棧string st;for (auto& e : s){if (st.size() && st.back() == e){st.pop_back();}else{st += e;}}return st;}
};

順利通過~

比較含退格的字符串😜

比較含退格的字符串

? ? ? ? 這一個題目與第一個題目類似,都是使用棧模擬這個過程,我們這里直接給出優化的算法思路~

算法思路字符串模擬棧實現過程

①根據題目要求,每一個字符串進行相同的變化(封裝成一個函數changeS)

②changS函數內部使用字符串模擬棧,當棧不為空并且當前字符為‘#'時,棧頂元素出棧;否則,當前字符不為’#‘就入棧(如果對空文本輸入退格字符,文本繼續為空)

③判斷兩個字符串變化后是否相等

代碼實現

//比較含退格的字符
class Solution
{
public:bool backspaceCompare(string s, string t){return changeS(s) == changeS(t);}string changeS(string s){string ret;for (auto& e : s){//當棧不為空并且當前字符為‘#'時,棧頂元素出棧if (ret.size() && e == '#'){ret.pop_back();}else if (e != '#')//小寫字母入棧{ret.push_back(e);}}return ret;}
};

順利通過~

基本計算器Ⅱ😀

基本計算器Ⅱ

? ? ? ? 題目要求我們實現一個簡單的計算器,我們這里給出一個巧妙的算法思路~

算法思路使用棧保存正數或者負數

棧存儲中間結果:棧用于存儲需要累加的值(正數或負數),乘除運算立即計算并更新棧頂

運算符延遲處理:遇到新運算符時只記錄,遇到下一個數字時才應用上一個運算符

處理優先級:通過立即計算乘除運算實現"先乘除后加減"

空格直接跳過

棧中所有數據相加就是計算結果

運算符處理規則

前一個運算符當前數字處理方式
+st.push(val)
-st.push(-val)
*st.top() *= val
/st.top() /= val

代碼實現

//基本計算器Ⅱ
class Solution
{
public:int calculate(string s){int n = s.size();char c = '+';//運算符號記錄stack<int> st;//棧保存計算結果int i = 0;//記錄下標while (i < n){//如果是空格,直接跳過!if (s[i] == ' ')i++;//如果是數字else if (s[i] >= '0' && s[i] <= '9'){//提取數字int val = 0;//保存數據while (s[i] >= '0' && s[i] <= '9'){val = val * 10 + (s[i] - '0');i++;}//判斷數字前面的運算符if (c == '+'){st.push(val);}else if (c == '-'){st.push(-val);}else if (c == '*'){st.top() *= val;}else if (c == '/'){st.top() /= val;}}//如果是其他,也就是運算符,更新符號else{c = s[i++];}}//取棧中元素相加,得到運算結果int ret = 0;while (!st.empty()){ret += st.top();st.pop();}//返回結果return ret;}
};

順利通過~這個題目也可以使用數組模擬棧實現功能,大家感興趣可以自己試一試~

字符串解碼😍

字符串解碼

? ? ? ? 我們需要根據要求進行字符串解碼,好在給出的字符串是沒有空格的,并且[ ]也是正確匹配的,我們可以進行分情況討論處理。

算法思路分情況討論

雙棧結構:使用兩個獨立棧協同工作

st_int:存儲數字(重復次數)

st_str:存儲字符串片段,初始化時st_str壓入空字符串""作為結果容器

四類字符處理邏輯

  • 數字(0-9):
    連續解析完整數字(如"12"→12),壓入st_int

  • 左括號([):
    提取后續連續小寫字母(如"[abc"→"abc"),作為新片段壓入st_str

  • 小寫字母(a-z):
    直接拼接到st_str棧頂字符串末尾

  • 右括號(]):
    彈出st_int棧頂數字nst_str棧頂字符串s,將s重復n次后拼接到新棧頂

嵌套解碼機制

遇到[時壓入新層級,遇到]時完成當前層級解碼:

  • 內層字符串先解碼(如3[c]→"ccc")

  • 結果拼接到外層字符串(如"ab"+"ccc"→"abccc")

  • 支持任意深度嵌套(如3[a2[c]]→"accaccacc")

結果生成

  • 最終返回st_str棧頂字符串:

    • 初始空字符串作為基礎容器

    • 所有層級解碼完成后棧頂即完整結果

    • 時間復雜度O(n),空間復雜度O(解碼字符串長度)

代碼實現

//字符串解碼
class Solution
{
public:string decodeString(string s){stack<int> st_int;//保存數字stack<string> st_str;//保存字符串st_str.push("");//插入空字符串,分別后續變形int i = 0;while (i < s.size()){//分情況討論//如果是數字,提取數字入數字棧if (s[i] >= '0' && s[i] <= '9'){int tmp = 0;while (s[i] >= '0' && s[i] <= '9'){tmp = 10 * tmp + (s[i] - '0');i++;}st_int.push(tmp);}//如果是[,提取后續字符保存到字符棧else if (s[i] == '['){i++;string tmp;while (s[i] >= 'a' && s[i] <= 'z'){tmp += s[i];i++;}st_str.push(tmp);}//如果是字符,那么加到字符棧棧頂字符串末尾else if (s[i] >= 'a' && s[i] <= 'z'){st_str.top() += s[i];i++;}//如果是],就取數字棧和字符棧棧頂,進行拼接else if (s[i] == ']'){string s = st_str.top();int n = st_int.top();st_int.pop();st_str.pop();for (int j = 0; j < n; j++){st_str.top() += s;//新字符棧拼接重復的字符}i++;}}return st_str.top();//字符棧頂就是需要的結果}
};

順利通過~

驗證棧序列😝

驗證棧序列

? ? ? 我們以前都做過類似的文字題,那么使用代碼怎么解決呢?答案是進行模擬就可以了~

算法思路使用棧模擬

模擬核心邏輯:使用棧 st 實時模擬入棧/出棧操作,指針 i 跟蹤 popped 序列當前位置,驗證其合法性

入棧與即時匹配:遍歷 pushed 序列:每個元素立即入棧,入棧后循環檢查:當棧非空且棧頂元素等于 popped[i] 時→ 彈出棧頂元素→ i 指針后移(匹配成功)

代碼實現

//驗證棧序列
class Solution
{
public:bool validateStackSequences(vector<int>& pushed, vector<int>& popped){stack<int> st;int i = 0;//用于遍歷出棧序列for (auto& e : pushed)//遍歷進棧序列{st.push(e);while (st.size() && st.top() == popped[i]){st.pop();i++;}}//通過判斷棧是否為空或者i是否走到末尾判斷是否為合法出棧序列return st.empty();//return i==popped.size();}
};

順利通過~


???本篇博客內容結束,期待與各位優秀程序員交流,有什么問題請私信???

???如果這一篇博客對你有幫助~別忘了點贊分享哦~???

??????個人主頁??????


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

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

相關文章

OpenAI 最新開源模型 gpt-oss (Windows + Ollama/ubuntu)本地部署詳細教程

OpenAI 最近發布了其首個開源的開放權重模型gpt-oss&#xff0c;這在AI圈引起了巨大的轟動。對于廣大開發者和AI愛好者來說&#xff0c;這意味著我們終于可以在自己的機器上&#xff0c;完全本地化地運行和探索這款強大的模型了。 本教程將一步一步指導你如何在Windows系統上&…

在X86架構Linux中創建虛擬根目錄并下載指定架構(如aarch64)的軟件包(含依賴)

在X86架構Linux中創建虛擬根目錄并下載指定架構(如aarch64)的軟件包(含依賴) 在Linux系統中&#xff0c;有時候我們需要在特定的環境或架構下安裝軟件包&#xff0c;而不影響主系統。一種常見的方法是創建一個虛擬的根目錄&#xff0c;并在此環境中操作。本文將介紹如何通過創建…

scratch筆記和練習-第9課:一起來繪畫

位圖也稱為點陣圖&#xff0c;它是由許許多多的點組成的&#xff0c;這些點被稱為像素。位圖圖像可以表現豐富的多彩變化 并產生逼真的效果&#xff0c;很容易在不同軟件之間交換使用&#xff0c; 但它在保存圖像時需要記錄每一個像素的色彩信息&#xff0c;所以占用的存儲空間…

[linux] Linux:一條指令更新DDNS

Linux&#xff1a;一條指令更新DDNS 在動態IP環境下&#xff0c;如何確保我們的域名始終指向正確的公網IP地址&#xff1f;動態DNS&#xff08;DDNS&#xff09;服務為我們提供了完美的解決方案。今天&#xff0c;我將分享一個簡潔高效的Linux命令行指令&#xff0c;用于自動更…

[激光原理與應用-182]:測量儀器 - 光束型 - 光束質量分析儀

光束質量分析儀是用于精確評估激光光束特性的核心設備&#xff0c;通過測量光束的強度分布、相位分布、發散角等參數&#xff0c;為激光系統的優化、加工工藝控制及科研實驗提供關鍵數據支持。以下是光束質量分析儀的詳細解析&#xff1a;一、核心功能 - 光束強度分布分析測量內…

Linux 限制 root 登錄 IP 地址的方法

Linux 限制 root 登錄 IP 地址的方法Linux 限制 root 登錄 IP 地址的方法方法一&#xff1a;修改 SSH 配置文件方法二&#xff1a;使用 hosts.allow 和 hosts.deny 文件方法三&#xff1a;使用防火墻規則方法四&#xff1a;使用 access.conf 文件注意事項Linux 限制 root 登錄 …

Word中怎樣插入特殊符號

使用 “插入” 菜單&#xff1a;插入常用符號&#xff1a;將光標置于要插入符號的位置&#xff0c;點擊 “插入” 選項卡&#xff0c;在 “符號” 組中點擊 “符號” 按鈕&#xff0c;會彈出一個符號庫&#xff0c;里面包含了常見的標點符號、特殊字符等&#xff0c;找到所需符…

Linux 內核發包流程與路由控制實戰

Linux 內核發包流程與路由控制實戰 在網絡調優、性能優化、SDN、NFV、容器網絡等場景下&#xff0c;理解 Linux 內核發包路徑和路由控制機制是必修課。 本文將從內核網絡棧的原理入手&#xff0c;再結合 iproute2 命令和 策略路由給出實戰案例。一、Linux 內核發包流程&#xf…

點播服務器

早期的時候&#xff0c;用 live555 作為 rtsp 點播服務器&#xff1b;現在比較常用的 流媒體服務器比較多&#xff1b;這里比較簡單的&#xff0c;可以用 ZLMediakit&#xff1b;可以支持 ffmeg 退流 到ZLMediakit&#xff0c;然后別的客戶端從 ZLMediakit 服務器拉流&#xff…

分享超圖提供的、很不錯的WebGIS學習資源

最近在學習了解Supermap iclient&#xff0c;發現官方提供的幫助文檔、GIS學堂真的不錯&#xff0c;解釋了很多的內容。 官方modern-web-gis-in-action文檔的網址如下&#xff1a;https://iclient.supermap.io/web/books/modern-web-gis-in-action/&#xff0c;在其中介紹了現代…

通信算法之298: verilog語法generate和for介紹

在 Verilog 中&#xff0c;generate和for是實現參數化設計和模塊實例化復用的重要工具&#xff0c;尤其在需要根據參數動態生成邏輯時非常有用。以下是它們的使用方法和區別&#xff1a;1. for循環&#xff08;過程塊內&#xff09;for循環主要用于過程塊&#xff08;always/in…

laravel在cli模式下輸出格式漂亮一些

在 Laravel 的 CLI 模式下&#xff0c;可以通過以下方式讓命令行輸出更加美觀和專業&#xff1a; 1. 使用 Artisan 輸出助手方法 Laravel 提供了多種輸出樣式方法&#xff1a; public function handle() {// 基礎樣式$this->info(成功信息 - 綠色); // 綠色$this->err…

大數據管理與應用學什么?就業前景怎么樣?

前言在數字經濟蓬勃發展的今天&#xff0c;大數據已經成為推動社會進步的核心生產要素。大數據管理與應用作為新興交叉學科&#xff0c;正受到越來越多學生和企業的關注。本文將全面剖析該專業的課程體系、核心技能要求&#xff0c;詳細介紹CDA數據分析師認證的備考策略&#x…

mac筆記本如何重新設置ssh key

要在Mac上重新生成SSH密鑰并將其添加到平臺&#xff0c;可以按照以下步驟操作&#xff1a; 打開終端 在Mac上&#xff0c;你可以通過Spotlight搜索&#xff08;按Command Space&#xff09;輸入Terminal來打開終端或者直接搜索終端檢查現有SSH密鑰 首先&#xff0c;檢查是否已…

Godot ------ 通過鼠標對節點進行操作

Godot ------ 通過鼠標對節點進行操作 引言 正文 引言 對于一個游戲,通過鼠標對游戲對象進行操作是非常普遍的行為,本文我們將以 Control 節點進行舉例,說明如何通過鼠標對 Control 節點進行移動操作。 正文 首先,我們創建一個 Contorl 節點,并將它的 Layout->Trans…

k8s 網絡插件 flannel calico

一、k8s 網絡概述 Kubernetes網絡是指在Kubernetes集群中不同組件之間進行通信和交互的網絡架構&#xff0c;每個容器都有自己的IP地址&#xff0c;這些容器組成了Pod&#xff0c;Pod是Kubernetes調度的最小單元。 Pod是Kubernetes中最小的部署單元&#xff0c;每個Pod都有一個…

易美教育榮膺“騰訊年度影響力國際教育品牌”雙獎加冕,見證中國國際教育力量的崛起

【騰訊新聞&#xff0c;北京訊】在剛剛圓滿落幕的“回響中國”騰訊新聞教育頻道年度論壇上&#xff0c;國際教育領域迎來了高光時刻&#xff1a;以美國華爾街為總部、深耕國際教育十余年的易美教育&#xff08;Easymay&#xff09;&#xff0c;憑借其持續創新的教育模式、國際化…

Chrome與Firefox瀏覽器安全運維配置命令大全:從攻防到優化的專業實踐

Chrome與Firefox瀏覽器安全運維配置命令大全&#xff1a;從攻防到優化的專業實踐 作者&#xff1a;高級網絡安全工程師 吉林?鎮賚融媒 劉曉偉 最后更新&#xff1a;2025年8月 適用對象&#xff1a;網絡安全、運維從業者 瀏覽器作為訪問互聯網資源的主要入口&#xff0c;其配置…

用 “故事 + 價值觀” 快速建立 IP 信任感

在知識變現、流量變現與粉絲變現的實踐中&#xff0c;IP 的核心競爭力在于用戶信任。“故事 價值觀” 的組合&#xff0c;能快速縮短與用戶的距離 —— 故事讓 IP 從抽象符號變為可感知的存在&#xff0c;價值觀則推動用戶從被動關注轉為主動認同&#xff0c;二者共同為變現筑…

PDF處理控件Aspose.PDF教程:使用 C#、Java 和 Python 代碼調整 PDF 頁面大小

使用 Aspose.PDF 調整 PDF 大小 Aspose.PDF 是一個功能強大且靈活的庫&#xff0c;旨在跨多個平臺&#xff08;包括 .NET、Java 和 Python&#xff09;處理 PDF 文件。在調整 PDF 大小方面&#xff0c;它提供了對頁面尺寸和內容縮放的完全控制。無論您是想縮小 PDF 大小、將頁…