關於 web service, unity, blogger 等軟體工程筆記

LeetCode #32 Longest Valid Parentheses

Edit icon 沒有留言
LeetCode using Golang

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

For "(()", the longest valid parentheses substring is "()", which has length = 2.

Another example is ")()())", where the longest valid parentheses substring is "()()", which has length = 4.

在旅行的過程中嘗試解這一題,剛開始第一直覺便想到可以使用 stack 來處理,利用 stack 先進先出的特性,來模擬先輸入 (,然後再輸入個 ) 時,利用 peek 來看是否有合用的 ( 來組成一組並且 pop,持續進行最後能找到結果,後來實作幾個版本後都無法滿足 test cases,後來重新思考想到一個簡單的解決方案……。

分析

計算輸入字串中,最長合法的括弧字串長度,例如輸入字串 ()((()),要能夠輸出 4

有效的括弧,不外乎是 () 兩兩配對,即使使巢狀的括弧,例如 (()),也會都是兩兩的配對。

利用這個條件,思考可以重新編碼字串,讓兩個配對的左右括弧編碼成 .,例如輸入字串 ()))(()),編碼成 .))..。如此一來只要找尋最長使用 . 組成的子字串長度,那便會是想要的答案。

因此利用上述思考其演算法,可使用 stack 先進先出的概念處理資料 (雖然實作上不是正統的 stack),其演算法:

  • 逐一列舉字串字元,用到左括號 (,一律直接 push 到 stack 中
  • 遇到右括號 ),stack 持續 pop,若遇到 (,則合併成 .,並且再 push 回 statck 中
  • 若 stack pop 遇到 . 則不管,因為那是合法的括號規則
  • 若發現 stack pop 到 empty,表示該右括號沒有對應的左括號,原先 pop 的資料依序在 push 回 stack 中,之後再將該右括號也 push 進 stack
  • 若 stack pop 遇到相同的右括號,那麼停止檢查,因為沒有合法的括號規則。此外相同的,原先 pop 的資料依序在 push 回 stack 中,之後再將該右括號也 push 進 stack
  • 反覆執行直到列舉完畢
  • 最後根據 stack 內容,找到最長合法的括號長度 (. 組成的子字串)

若輸入字串為 ()))(()),其資料圖解:

資料圖解

解法

使用 Go:

func longestValidParentheses(s string) int {
   // Encode parentheses by validing rules
   q := make([]rune, 0, len(s))
   for _, c := range s {
      if c == '(' {
         q = append(q, c)
      } else if c == ')' {
         q = append(q, c)
      L:
         for i := len(q) - 2; i >= 0; i-- {
            switch q[i] {
            case '(':
               q[i] = '.'
               q = q[:len(q)-1]
               break L
            case ')':
               break L
            }
         }
      }
   }
   
   // Find longest ... substring
   max := 0
   cur := 0
   for _, c := range q {
      if c == '.' {
         cur += 1
         if cur > max {
            max = cur
         }
      } else {
         cur = 0
      }
   }
   return max * 2
}

不過看過其他人的解法後,可以直接修改改用 index 操作,這樣就不用進行編碼再計算合法括號的長度了……。

沒有留言: