LeetCode 32 - Longest Valid Parentheses
題目
題目連結:https://leetcode.com/problems/longest-valid-parentheses/
給定一個只包含 '('
和 ')'
的字串 s
,找到最長的合法括號子字串。
範例說明
Example 1:
1 | Input: "(()" |
Example 2:
1 | Input: ")()())" |
想法
首先,要判斷一個字串是否為合法的括號字串。一個合法的括號,若且唯若,字串左括號的數量一定要等於右括號的數量,且由左至右數任一個時刻,左括號的數量都應該大於等於右括號出現的數量。
要判斷字串是否有上述的性質,可以使用一個 stack
,stack
為先進後出(First-in-last-out, FILO)之資料結構。給定之字串由左至右,每次遇到左括號,就將左括號放入 stack
之中;反之,遇到右括號時,將 stack
之頂端元素拿出。stack
之頂端左括號即為當前右括號之匹配。若 stack
為空,代表右括號出現的數量比左括號還多,此字串為不合法的字串。若遍歷完字串後 stack
內還有剩餘元素,代表左括號數量大於右括號,所以此字串也非合法字串。
有了上述概念,此題目要求最長合法括號子字串。額外紀錄當前合法區間的左邊界 left
,一開始為 left = -1
代表目前整個字串都是合法的。字串左至右,如果遇到左括號,則加入 stack
之中。當遇到右括號時:
stack
為空,代表此右括號沒有任何任何左括號可以匹配,更新left
等於此右括號的索引。stack
不為空:將右括號所匹配的左括號從stack
移除。- 如果
stack
內還有元素,則右括號到stack
的頂端左括號之間都是合法括號子字串。 - 如果
stack
為空,則右括號到上述紀錄的合法區間左邊界都是合法括號子字串。
- 如果
每一個字元都只遍歷一次,若字串長度為 N
,總時間複雜度為 O(N)
。
實作細節
實作上為了方便,筆者將 left
推入 stack
之中,如此一來,當遇到右括號時:
stack
頂端元素等於left
,代表此右括號沒有任何任何左括號可以匹配,更新left
等於右括號的索引,並將此合法邊界推入stack
之中。stack
頂端元素不等於left
:將右括號所匹配的左括號從stack
移除,右括號到stack
的頂端元素之間都是合法括號子字串。
程式碼
1 | /** |