给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
示例 2:
输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”
解题思路
栈+排序
括号匹配,第一时间想到用栈进行匹配,保存下可以匹配的索引下标。然后将匹配索引排序,找到最长连续子序列。
-
初试化栈stack = []和匹配索引数组res = []
-
遍历括号字符串:
∘\circ∘ 若s[i] == “(”,若出现左括号,将其索引加入栈。
∘\circ∘ 若stackstack不为空且s[i] == “)”,表示出现右括号,且栈里有左括号。将匹配的左括号的索引stack.pop()加入resres中 将匹配的右括号索引i加入栈。 -
将resres排序。
-
初始化最长长度max_len=0,寻找res的最长连续子序列。循环条件,i<len(res)−1:
∘\circ∘令tmp=i保存最长连续子序列的左界
∘\circ∘ 进入循环,循环条件i<len(res)-1且下一位和当前位差为1,res[i+1]−res[i]==1:令i=i+1i=i+1∘\circ∘ max_len=max(max_len,i-tmp+1)
∘\circ∘ i+=1 -
返回max_len
复杂度分析
- 时间复杂度:O(nlog(n)),括号匹配O(n),排序复杂度O(nlog(n)),寻找最长连续子序列O(n),总体O(nlog(n))
- 空间复杂度:O(n)
class Solution:
def longestValidParentheses(self, s: str) -> int:
res=[]
stack=[]
for i in range(len(s)):
if(stack and s[i]==")"):
res.append(stack.pop())
res.append(i)
if(s[i]=="("):
stack.append(i)
#print(res)
res.sort()
max_len=0
i=0
while(i<len(res)-1):
tmp=i
while(i<len(res)-1 and res[i+1]-res[i]==1):
i+=1
max_len=max(max_len,i-tmp+1)
i+=1
return max_len
栈(优化)
-
特判,若s为空,返回0
-
初始化栈stack=[-1],和结果res=0。栈中元素表示上一不匹配位置索引。
-
遍历s:
∘\circ∘ 若s[i] == “(” 将当前位置索引加入stackstack。表示将当前左括号需要匹配,为不匹配索引。
∘\circ∘ 若s[i]==")":- 出栈,stack.pop()。表示将对应左括号索引出栈,或者当栈中只有)时,将上一)索引出栈。
- 若栈为空,表示之前的所有的(匹配成功,上一步出栈的是栈底的-1或者是前一个不匹配的)。则更新栈底为当前)的索引,表示不匹配的位置。
- 否则,说明和栈中的(匹配上了,此时更新最长序列res=max(res,i-stack[-1])。表示当前位置索引减去上一不匹配位置索引 和之前res中的较大值。
-
更新res
复杂度分析
- 时间复杂度:O(n)
- 空间复杂度:O(n)
class Solution:
def longestValidParentheses(self, s: str) -> int:
if(not s):
return 0
stack=[-1]
res=0
for i in range(len(s)):
if(s[i]=="("):
stack.append(i)
else:
stack.pop()
if(not stack):
stack.append(i)
else:
res=max(res,i-stack[-1])
return res
本文介绍了一种使用栈和排序解决最长有效括号子串问题的方法,通过遍历括号字符串并利用栈来记录匹配的索引,再对这些索引进行排序,最后找出最长的连续子序列。
732

被折叠的 条评论
为什么被折叠?



