【LeetCode數據結構】棧的應用——有效的括號問題詳解


?🔥個人主頁:艾莉絲努力練劍

?專欄傳送門:《C語言》、《數據結構與算法》、C語言刷題12天IO強訓、LeetCode代碼強化刷題

🍉學習方向:C/C++方向

??人生格言:為天地立心,為生民立命,為往圣繼絕學,為萬世開太平


?


前言:牛客網和LeetCode的刷題都不可或缺,我們都要做一做,無論是參加競賽還是筆試面試,至少能提升你的代碼能力!洛谷的題目也可以去做一做。力扣的題目對提升代碼能力很有幫助,需要有一點基礎,幾乎都是接口型的題目,關于接口型和IO型的區別我們在本專欄的第一篇【LeetCode】力扣題——輪轉數組、消失的數字、數組串聯中就介紹過了,這里不再贅述,我們進入今天的力扣題目介紹——


目錄

正文?

一、有效的括號

1、思路

2、解題過程

3、改進方案?

4、其他思路——有局限性的一種思路

結尾


正文?

一、有效的括號

鏈接:20. 有效的括號

博主題解鏈接:借助數據結構——棧——解決經典例題【有效的括號】

推薦大家可以直接去看博主在力扣上面寫的題解,博主介紹的還是比較詳細的,博主寫題解,尤其是數據結構算法題的題解,都是畫圖加說明,簡單易懂。

題目描述:?

除了示例,本題也給了這樣一個提示——?

1、思路

我們的思路是:

借助數據結構——棧,遍歷字符串,左括號入棧,是右括號就取棧頂元素比較,看是否匹配。

我們先來看看題目描述——

分析一下題目的意思——?

2、解題過程

像這種題目拿到手我們首先就是想到要畫圖,一定要有這個意識,數據結構的算法題一定要畫圖。

注意是取棧頂,可不是出棧頂哦!

接下來我們就可以寫代碼了——??

代碼演示:?

//定義棧的結構
typedef char STDataType;
typedef struct Stack
{STDataType* arr;int top;//定義棧中有效的數據個數int capacity;//棧的空間大小
}ST;//初始化
void STInit(ST* ps)
{ps->arr = NULL;ps->top = ps->capacity = 0;
}//銷毀
void STDestory(ST* ps)
{if (ps->arr)free(ps->arr);ps->arr = NULL;ps->top = ps->capacity = 0;
}//入棧——棧頂
void STPush(ST* ps, STDataType x)
{assert(ps);//判斷空間是否足夠if (ps->top == ps->capacity){//增容int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* tmp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}//空間足夠ps->arr[ps->top++] = x;
}//棧是否為空
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}//出棧——棧頂
void STPop(ST* ps)
{assert(!STEmpty(ps));ps->top--;
}//取棧頂元素
STDataType STTop(ST* ps)
{assert(!STEmpty(ps));return ps->arr[ps->top - 1];
}//獲取棧中有效元素個數
int STSize(ST* ps)
{assert(ps);return ps->top;
}
//-----------------------以上是棧結構定義和常見方法-------------------------
bool isValid(char* s) 
{//借助數據結構——棧ST st;STInit(&st);char* pi = s;while(*pi != '\0'){//左括號入棧if(*pi == '(' || *pi == '[' || *pi == '{'){STPush(&st,*pi);}else{//右括號——取棧頂,比較,匹配則出棧,不匹配直接返回false//棧不為空才能取棧項if(STEmpty(&st)){STDestory(&st);return false;}char top = STTop(&st);if((top == '(' && *pi != ')')||(top == '[' && *pi != ']')||(top == '{' && *pi != '}')){STDestory(&st);return false;}//本次是匹配的——出棧STPop(&st);}pi++;}//判斷棧是否為空,為空有效,非空無效if(STEmpty(&st)){STDestory(&st);return true;}STDestory(&st);return false;STDestory(&st);return ret;
}

復雜度:時間復雜度:O(N),空間復雜度:O(1)

3、改進方案?

最后我們【判斷棧是否為空,為空有效,非空無效】那里代碼太長了,我們用一個三目表達式就可以把它替換下來,這就是改進方案。

代碼演示:

//定義棧的結構
typedef char STDataType;
typedef struct Stack
{STDataType* arr;int top;//定義棧中有效的數據個數int capacity;//棧的空間大小
}ST;//初始化
void STInit(ST* ps)
{ps->arr = NULL;ps->top = ps->capacity = 0;
}//銷毀
void STDestory(ST* ps)
{if (ps->arr)free(ps->arr);ps->arr = NULL;ps->top = ps->capacity = 0;
}//入棧——棧頂
void STPush(ST* ps, STDataType x)
{assert(ps);//判斷空間是否足夠if (ps->top == ps->capacity){//增容int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;STDataType* tmp = (STDataType*)realloc(ps->arr, newCapacity * sizeof(STDataType));if (tmp == NULL){perror("realloc fail!");exit(1);}ps->arr = tmp;ps->capacity = newCapacity;}//空間足夠ps->arr[ps->top++] = x;
}//棧是否為空
bool STEmpty(ST* ps)
{assert(ps);return ps->top == 0;
}//出棧——棧頂
void STPop(ST* ps)
{assert(!STEmpty(ps));ps->top--;
}//取棧頂元素
STDataType STTop(ST* ps)
{assert(!STEmpty(ps));return ps->arr[ps->top - 1];
}//獲取棧中有效元素個數
int STSize(ST* ps)
{assert(ps);return ps->top;
}
//-----------------------以上是棧結構定義和常見方法-------------------------
bool isValid(char* s) 
{//借助數據結構——棧ST st;STInit(&st);char* pi = s;while(*pi != '\0'){//左括號入棧if(*pi == '(' || *pi == '[' || *pi == '{'){STPush(&st,*pi);}else{//右括號——取棧頂,比較,匹配則出棧,不匹配直接返回false//棧不為空才能取棧項if(STEmpty(&st)){STDestory(&st);return false;}char top = STTop(&st);if((top == '(' && *pi != ')')||(top == '[' && *pi != ']')||(top == '{' && *pi != '}')){STDestory(&st);return false;}//本次是匹配的——出棧STPop(&st);}pi++;}//判斷棧是否為空,為空有效,非空無效// if(STEmpty(&st))// {//     STDestory(&st);//     return true;// }// STDestory(&st);// return false;//寫成三目表達式bool ret = STEmpty(&st) ? true : false;STDestory(&st);return ret;
}

復雜度:時間復雜度:O(N),空間復雜度:O(1)

代碼只有一個循環遍歷,其它的都是條件判斷,時間復雜度O(N),也沒有額外申請空間,故空間復雜度O(1),復雜度較優。

4、其他思路——有局限性的一種思路


結尾

往期回顧:

【LeetCode&數據結構】單鏈表的應用——隨機鏈表的復制問題、相交鏈表問題詳解

【牛客&LeetCode&數據結構】單鏈表的應用——移除鏈表元素問題、鏈表分割問題詳解

【牛客&LeetCode&數據結構】單鏈表的應用——合并兩個有序鏈表問題、鏈表的回文結構問題詳解

【LeetCode&數據結構】單鏈表的應用——反轉鏈表問題、鏈表的中間節點問題詳解

【LeetCode】力扣題——輪轉數組、消失的數字、數組串聯

【LeetCode】力扣題——輪轉數組、消失的數字、數組串聯

結語:本篇文章到這里就結束了,本文講述的兩道代碼題并不適合C語言初學者,需要有一定的C語言基礎,最好要學過數據結構與算法的算法復雜度和鏈表的知識,才能寫出復雜度較優的代碼來。大家一定要自己動手敲一敲,不敲的話不僅容易忘記,也不方便將來復習。

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

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

相關文章

多尺度卷積模型:Inception塊

在GoogLeNet中,基本的卷積塊被稱為Inception塊(Inception block)。 使用窗口大小為11,33,551\times1,3\times3,5\times511,33,55的卷積層,從不同空間大小中提…

Android 默認圖庫播放視頻沒有自動循環功能,如何添加

Android 默認圖庫播放視頻沒有自動循環功能, 如何添加 按如下方式添加 開發云 - 一站式云服務平臺 .../apps/Gallery2/res/values-zh-rCN/strings.xml | 3 ++ packages/apps/Gallery2/res/values/strings.xml | 3 ++ .../com/android/gallery3d/app/MovieActivity…

7月21日總結

命令執行 RCE RCE(remote code execute):遠程命令執行或者代碼執行,我們平時說的rce,比如thinkPHP的 rce漏洞,即算代碼注入漏洞,也算rce漏洞,因為滲透的最終情況可以實現執行命令或…

Linux——自制shell命令行解釋器

文章目錄1.打印命令提示符2.獲取用戶輸入指令3.重定向分析4.命令行參數表,環境變量表,初始化5.命令解析6.命令執行6.1.創建子進程6.2 處理內建命令6.3 文件重定向7.源碼前言 在實現shell的時候我們先創建自己myshell目錄,在目錄中創建myshell.cc文件,因…

Boost庫智能指針boost::shared_ptr詳解和常用場景使用錯誤示例以及解決方法

1、Boost智能指針 —— boost::shared_ptr 詳解一、什么是 boost::shared_ptr boost::shared_ptr 是 Boost 庫中實現的一個智能指針模板類,用于管理動態分配的對象生命周期,采用引用計數機制。多個 shared_ptr 實例可以共享同一個對象的所有權&#xff0…

科學分析指南,如何快速找到并清理磁盤的無用文件

隨著時間的推移,系統中會積累大量的臨時文件、緩存文件、不再需要的安裝包或其他大型文件。磁盤清理可以刪除這些不必要的文件,從而釋放寶貴的磁盤空間。它無需安裝,插上 U 盤就能直接使用。只需勾選需要掃描的磁盤,點擊“開始分析…

Laravel 系統版本查看及artisan管理員密碼找回方法針對各個版本通用方法及原理-優雅草卓伊凡

Laravel 系統版本查看及artisan管理員密碼找回方法針對各個版本通用方法及原理-優雅草卓伊凡一、查看 Laravel 版本的方法優雅草蜻蜓T會議系統專業版 最近又有客戶要了,但是發現 密碼不對 管理員賬戶密碼不對,卓伊凡必須處理下,這里順便講解密…

針對大規模語言模型的上下文工程技術調研與總結(翻譯并摘要)

針對大規模語言模型的上下文工程技術調研與總結聲明摘要部分翻譯介紹部分翻譯相關工作部分翻譯并摘要為什么使用上下文工程(翻譯并摘要)基礎組件(翻譯并摘要)RAG(翻譯并摘要簡單介紹一下個人認為比較好的技術&#xff…

QT配置Quazip外部庫

1.下載QuaZip源碼網址:https://sourceforge.net/projects/quazip/  注:下載->解壓->打開.pro文件2.編譯QuaZip源碼2.1配置zlib注:QuaZip需zlib的支持,我們需要引用zlib找到本地安裝Qt目錄下zlib目錄:注&#x…

從C++開始的編程生活(4)——類的定義、訪問限定符、類域、類的實例化和this指針

前言 本系列文章承接C語言的學習,需要有C語言的基礎才能學會哦~ 第3篇主要講的是有關于C的類的定義、訪問限定符、類域、類的實例化和this指針。 C才起步,都很簡單呢! 目錄 前言 類 基本語法 訪問限定符 基本語法 類域 類的實例化 內…

AD域控制器虛擬化的安全加固最佳實踐

以下是AD域控制器虛擬化安全加固的7項核心實踐,結合最新Windows Server 2022特性與虛擬化環境需求:基礎架構強化? 采用靜態IP分配并確保所有域控節點DNS指向主DC(如192.168.1.10)? 虛擬機模板需預配置林/域功能級別為Windows Se…

java解析nc氣象數據

1.1pom.xml<dependency><groupId>edu.ucar</groupId><artifactId>netcdfAll</artifactId><version>5.4.1</version></dependency>1.2 netcdf使用/** param type 0 ,1, 2 wind 1 or 2 其他 0 .* return Map* */public Map i…

STC8H8K64U SKDIP28芯片頻率占空比PWM波形

/****PWM輸出任意周期占空比波形*******/ #include "STC8H.h" // #include "intrins.h" // #define uchar unsigned char // #define uint unsig…

【RK3576】【Android14】USB開發調試

獲取更多相關的【RK3576】【Android14】驅動開發&#xff0c;可收藏系列博文&#xff0c;持續更新中&#xff1a; 【RK3576】Android 14 驅動開發實戰指南 硬件接口 RK3576支持兩個USB3.0控制器 驅動開發 dts配置 在“Android14/kernel-6.1/arch/arm64/boot/dts/rockchip/rk…

20. TaskExecutor與ResourceManager心跳

20. TaskExecutor與ResourceManager心跳 現在&#xff0c;需要回過頭看 ResourceManager是如何產生心跳管理服務的。cluster.initializeServices 方法的 heartbeatServices createHeartbeatServices(configuration);產生一個 HeartbeatServicesImpljobmanager的 resourceManag…

OS19.【Linux】進程狀態(上)

目錄 1.情景引入 2.操作系統學科對進程狀態的分類 運行狀態 基于時間片的輪轉調度算法 阻塞狀態 等待IO設備的例子 等待其他進程中需要獲取的數據 進程喚醒 掛起狀態(全稱為阻塞掛起狀態) 簡單談談虛擬內存管理 就緒狀態 筆面試題 3.Linux對進程狀態的分類 R和S狀…

如何優雅地修改項目的 Android 版本(API 級別)

引言 在 Android 開發的日常迭代中&#xff0c;我們經常需要升級或降級項目的 minSdkVersion、targetSdkVersion 與 compileSdkVersion。升級可以解鎖新特性和性能優化&#xff1b;降級則可能為了兼容舊機型或快速驗證問題。本文將手把手演示在 Android Studio 里修改 Android …

GNU Radio多類信號多種參數數據集生成技巧

參考我的這篇博客&#xff0c;我想自制一個多信號數據集&#xff1a; 【多雷達信號硬件模擬】 3臺USRP1臺VSG信號發生器模擬多雷達信號&#xff0c;1臺USRP產生高斯噪聲模擬更多信道環境&#xff0c;1臺USRP采集信號 需要在多個波段對四種信號進行參數設置&#xff0c;帶寬有…

Ansible + Shell 服務器巡檢腳本

腳本概述這是一個用于服務器日常巡檢的 Shell 腳本&#xff0c;主要功能包括&#xff1a;檢查多臺主機的網絡連通性 監控CPU、內存和磁盤使用率 生成詳細的巡檢報告 通過企業微信發送告警通知核心技術點1. 主機批量管理使用Ansible工具遠程執行命令和腳本 通過主機…

Linux-rpm和yum

一、RPMRPM&#xff08;Red Hat Package Manager&#xff09;是一個用于管理 Red Hat 系列 Linux 發行版&#xff08;如 RHEL、CentOS、Fedora&#xff09;軟件包的工具。RPM 允許用戶以統一的格式來安裝、卸載、升級和查詢軟件包。它是 .rpm 文件的主要工具&#xff0c;后綴名…