32. 最长有效括号
题目描述
给你一个只包含 '('
和 ')'
的字符串,找出最长有效(格式正确且连续)括号子串的长度。
示例 1:
输入:s = "(()" 输出:2 解释:最长有效括号子串是 "()"
示例 2:
输入:s = ")()())" 输出:4 解释:最长有效括号子串是 "()()"
示例 3:
输入:s = "" 输出:0
提示:
0 <= s.length <= 3 * 104
s[i]
为'('
或')'
解法
方法一:动态规划
我们定义 \(f[i]\) 表示以 \(s[i-1]\) 结尾的最长有效括号的长度,那么答案就是 \(\max\limits_{i=1}^n f[i]\)。
- 如果 \(s[i-1]\) 是左括号,那么以 \(s[i-1]\) 结尾的最长有效括号的长度一定为 \(0\),因此 \(f[i] = 0\)。
- 如果 \(s[i-1]\) 是右括号,有以下两种情况:
- 如果 \(s[i-2]\) 是左括号,那么以 \(s[i-1]\) 结尾的最长有效括号的长度为 \(f[i-2] + 2\)。
- 如果 \(s[i-2]\) 是右括号,那么以 \(s[i-1]\) 结尾的最长有效括号的长度为 \(f[i-1] + 2\),但是还需要考虑 \(s[i-f[i-1]-2]\) 是否是左括号,如果是左括号,那么以 \(s[i-1]\) 结尾的最长有效括号的长度为 \(f[i-1] + 2 + f[i-f[i-1]-2]\)。
因此,我们可以得到状态转移方程:
\[
\begin{cases}
f[i] = 0, & \textit{if } s[i-1] = '(',\\
f[i] = f[i-2] + 2, & \textit{if } s[i-1] = ')' \textit{ and } s[i-2] = '(',\\
f[i] = f[i-1] + 2 + f[i-f[i-1]-2], & \textit{if } s[i-1] = ')' \textit{ and } s[i-2] = ')' \textit{ and } s[i-f[i-1]-2] = '(',\\
\end{cases}
\]
最后返回 \(\max\limits_{i=1}^n f[i]\) 即可。
时间复杂度 \(O(n)\),空间复杂度 \(O(n)\)。其中 \(n\) 为字符串的长度。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
方法二:使用栈
- 使用栈来存储左括号的索引,栈底元素初始化为
-1
,用于辅助计算有效括号的长度。 - 遍历字符串,对于每个字符:
- 如果是左括号,将当前位置压入栈。
- 如果是右括号,弹出栈顶元素表示匹配了一个左括号。
- 如果栈为空,说明当前右括号无法匹配,将当前位置压入栈作为新的起点。
- 如果栈不为空,计算当前有效括号子串的长度,更新最大长度。
- 最终返回最大长度。
总结:这个算法的关键在于维护一个线,栈内存放的是左括号的索引,通过弹出和压入的操作来更新有效括号子串的长度。
时间复杂度 \(O(n)\),空间复杂度 \(O(n)\)。其中 \(n\) 为字符串的长度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
|