題幹以下:git
給定一個只包括 '(',')','{','}','[',']' 的字符串,判斷字符串是否有效。
有效字符串需知足:
1.左括號必須用相同類型的右括號閉合。
2.左括號必須以正確的順序閉合。
3.注意空字符串可被認爲是有效字符串。
示例 1:
輸入: "()"
輸出: true
示例 2:
輸入: "()[]{}"
輸出: true
示例 3:
輸入: "(]"
輸出: false
示例 4:
輸入: "([)]"
輸出: false
示例 5:
輸入: "{[]}"
輸出: true
來源:力扣
這題是我大學老師教 棧 這種數據結構的應用場景時講解的題目,稍微有一丟丟懷念。
解題思路很簡單:從左到右遍歷字符串,遇到 左括號: [ ( { 就壓入棧中,遇到 右括號: ] ) } 就拿 棧頂元素 與 當前元素 匹配,是不是一對括號。是,則繼續遍歷,不是,則直接返回 false。github
注:
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{ } }
下面的代碼實現,基於上面的數據結構:app
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 }
在用 棧 解題的過程當中會發現: 若是字符串是有效括號,那麼一
定存在一對相鄰的括號,而且第一個匹配的右括號,左邊的元素必定是
相對應的左括號。spa
基於上面的認知,咱們將這對相鄰的括號替換成空字符串,剩下的字符串,若是是有效字符串,仍會存在一對相鄰的括號,同理再替換,依次循環。若是不存在一對相鄰的括號,而且最後剩下的字符串爲空了,那麼原始字符串就是有效括號,不然不是。3d
流程圖以下:code
具體的代碼實現以下:( 只是提供一種思路,這種實現方式時間複雜度有點高 )blog
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/learning-algorithm教程