讓咱們一塊兒啃算法----有效的括號

有效括號(Valid-Parentheses)

題幹以下:git

給定一個只包括 '(',')','{','}','[',']' 的字符串,判斷字符串是否有效。
有效字符串需知足:
  1.左括號必須用相同類型的右括號閉合。
  2.左括號必須以正確的順序閉合。
  3.注意空字符串可被認爲是有效字符串。
示例 1:
  輸入: "()"
  輸出: true
示例 2:
  輸入: "()[]{}"
  輸出: true
示例 3:
  輸入: "(]"
  輸出: false
示例 4:
  輸入: "([)]"
  輸出: false
示例 5:
  輸入: "{[]}"
  輸出: true
來源:力扣

解題思路

這題是我大學老師教 這種數據結構的應用場景時講解的題目,稍微有一丟丟懷念
解題思路很簡單:從左到右遍歷字符串,遇到 左括號: [ ( { 就壓入棧中,遇到 右括號: ] ) } 就拿 棧頂元素當前元素 匹配,是不是一對括號。是,則繼續遍歷,不是,則直接返回 falsegithub

注:
  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教程

相關文章
相關標籤/搜索