Leetcode演算法——32、最長有效括號字串
阿新 • • 發佈:2018-11-08
給定一個字串,只包含’(‘和’)’。
要求找到最長的有效的子串。
Example 1:
Input: “(()”
Output: 2
Explanation: The longest valid parentheses substring is “()”
Example 2:
Input: “)()())”
Output: 4
Explanation: The longest valid parentheses substring is “()()”
思路
1、暴力法
使用棧來判斷一個子串是否是有效子串。參考判斷有效括號。
構建多個棧,每個棧的作用是判斷從當前字元開始到s結束的子串是否是有效子串。
步驟:
1、掃描一次,每掃描到一個字元,就比對所有的棧,看是否是有效子串。
2、如果掃描到了左括號,還需要開闢一個新的棧。
3、掃描過程中,每當棧變為空,說明發現了一串有效字串,記錄所有有效字串的最長長度。
2、反推法
仍然使用棧來判斷有效字串,但只需要構造一個棧,也只需要掃描一遍。
掃描完之後,這個棧中剩下的字元,都是匹配不上另一半的字元。不在棧內的索引是可以匹配上的,因此棧內相鄰索引之間的子串為有效子串。
相鄰索引的差值,即為有效子串的長度。
最後從所有相鄰索引的差值中找到最大值即可。
python實現
def longestValidParentheses (s):
"""
:type s: str
:rtype: int
構建多個棧,
每個棧的作用是判斷從當前字元開始到s結束的子串是否是有效子串。
"""
if len(s) <= 1:
return 0
stack_list = [] # 每個元素為 (stack, start_idx)
max_len = 0
for i in range(len(s)):
char = s[i]
if char == '(':
# 所有棧追加符號
for stack in stack_list:
stack[0].append(char)
# 開闢一個新的棧
stack_list.append(([char], i))
else:
for j in range(len(stack_list)-1, -1, -1):
stack = stack_list[j]
if not stack[0] or stack[0].pop() != '(':
del stack_list[j]
continue
if not stack[0]: # 恰好棧變為空
max_len = max(max_len, i - stack[1] + 1)
return max_len
def longestValidParentheses2(s):
"""
:type s: str
:rtype: int
構造一個棧,
相鄰索引的差值,即為有效子串的長度。
"""
l = len(s)
# 掃描一遍,構造一個棧,最後只剩下匹配不上的索引
stack = []
for i in range(l):
if s[i] == ')' and stack and s[stack[-1]] == '(':
stack.pop()
else:
stack.append(i)
# 不在棧內的索引是可以匹配上的,統計其中的最長子串
if not stack:
return l
stack.insert(0, -1)
stack.append(l)
return max(stack[i+1]-stack[i]-1 for i in range(len(stack)-1))
if '__main__' == __name__:
s = ")"
print(longestValidParentheses2(s))