1. 程式人生 > >Leetcode演算法——32、最長有效括號字串

Leetcode演算法——32、最長有效括號字串

給定一個字串,只包含’(‘和’)’。

要求找到最長的有效的子串。

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))