有效括號(Valid-Parentheses)
題幹如下:
給定一個只包括 ‘(‘,’)’,’{‘,’}’,’[‘,’]’ 的字串,判斷字串是否有效。
有效字串需滿足:
1.左括號必須用相同型別的右括號閉合。
2.左括號必須以正確的順序閉合。
3.注意空字串可被認為是有效字串。
示例 1:
輸入: “()”
輸出: true
示例 2:
輸入: “()[]{}”
輸出: true
示例 3:
輸入: “(]”
輸出: false
示例 4:
輸入: “([)]”
輸出: false
示例 5:
輸入: “{[]}”
輸出: true
來源:力扣
解題思路
這題是我大學老師教 棧 這種資料結構的應用場景時講解的題目,稍微有一丟丟懷念。
解題思路很簡單:從左到右遍歷字串,遇到 左括號: [ ( { ** 就壓入棧中,遇到 **右括號: ] ) } 就拿 棧頂元素 與 當前元素 匹配,是否是一對括號。是,則繼續遍歷,不是,則直接返回 false。
注:
1. 棧 是一種很常見的資料結構,特點是先進後出
2. 棧頂元素 每次比較之後都要從棧中移除,即 pop 操作
3. 為什麼是遇到 左括號 將其壓入棧中呢?假設我們將 右括號 壓入棧中,由於我們是從左往右遍歷的,當遇到 左括號 時假設我們取出棧頂元素 右括號 進行比較,這時候有一個問題:當前比較的 左括號 的位置其實是在 右括號 之後的,即類似 ][。
聰明的小夥伴一定猜到了,當我們從右向左遍歷時,壓入棧的就是 右括號 啦。
流程圖如下:
程式碼實現
由於需要基於 棧 這種資料結構來解題,我簡單用 go 實現了一個棧:
type Stack struct {
stack []byte // 存放位元組
length int // 內部維護的長度
}
// 壓棧
func (s *Stack) push(b byte) {
s.stack = append(s.stack,b)
s.length ++
}
// 出棧
func (s *Stack) pop() (res byte) {
if s.length <= 0 {
return
}
s.length --
res = s.stack[s.length]
s.stack = s.stack[0:s.length]
return
}
// 判斷棧是否為空
func (s *Stack) isEmpty() bool {
return s.length <= 0
}
// 構造
func getStack() *Stack {
return &Stack{
}
}
下面的程式碼實現,基於上面的資料結構:
func isValid(s string) bool {
if len(s) <= 0 {
return true
}
// 例項化棧
stack := getStack()
for i := 0; i < len(s); i++ {
// 判斷是左括號就壓入棧
if s[i] == '(' || s[i] == '[' || s[i] == '{' {
stack.push(s[i])
} else {
// 如果棧為空,這時候 i 沒有越界,則返回 false
if stack.isEmpty() {
return false
}
// 獲取棧頂元素
top := stack.pop()
// 比較是否匹配
if '(' == top && s[i] != ')' || '[' == top && s[i] !=']' || '{' == top && s[i] !='}'{
return false
}
}
}
// 如果 i 越界,並且 棧 為空,則返回 true
if stack.isEmpty() {
return true
}
return false
}
擴充套件思路
在用 棧 解題的過程中會發現: 如果字串是有效括號,那麼一
定存在一對相鄰的括號,並且第一個匹配的右括號,左邊的元素一定是
相對應的左括號。
基於上面的認知,我們將這對相鄰的括號替換成空字串,剩下的字串,如果是有效字串,仍會存在一對相鄰的括號,同理再替換,依次迴圈。如果不存在一對相鄰的括號,並且最後剩下的字串為空了,那麼原始字串就是有效括號,否則不是。
流程圖如下:
具體的程式碼實現如下:( 只是提供一種思路,這種實現方式時間複雜度有點高 )
func isValidOther(s string) bool {
// 判斷是否有一對相鄰的括號
for strings.Index(s,"()") != -1 || strings.Index(s,"[]") != -1 || strings.Index(s,"{}") != -1 {
// 存在,則替換成 空字串, 繼續下次判斷
s = strings.Replace(s,"()","",-1)
s = strings.Replace(s,"[]","",-1)
s = strings.Replace(s,"{}","",-1)
}
// 如果不存在一對相鄰的括號,並且剩餘的字串長度不為0,則返回 false
if len(s) >= 1 {
return false
}
return true
}
總結
每天進步一點點,加油!
演算法教程專案,每天更新一題,點個 star 支援一下呀:https://github.com/wx-satellite/go-leetcod...
本作品採用《CC 協議》,轉載必須註明作者和本文連結