LeetCode #32 Longest Valid Parentheses
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 操作,這樣就不用進行編碼再計算合法括號的長度了……。


沒有留言: