给你一个只包含 '('
和 ')'
的字符串,找出最长有效(格式正确且连续)括号子串的长度。
示例 1:
输入:s = "(()" 输出:2 解释:最长有效括号子串是 "()"
示例 2:
输入:s = ")()())" 输出:4 解释:最长有效括号子串是 "()()"
示例 3:
输入:s = "" 输出:0
提示:
0 <= s.length <= 3 * 104
s[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]$ 。
- 如果
因此,我们可以得到状态转移方程:
最后,我们只需要返回
时间复杂度
class Solution:
def longestValidParentheses(self, s: str) -> int:
n = len(s)
if n < 2:
return 0
f = [0] * (n + 1)
for i in range(2, n + 1):
if s[i - 1] == ')':
if s[i - 2] == '(':
f[i] = f[i - 2] + 2
else:
j = i - f[i - 1] - 1
if j > 0 and s[j - 1] == '(':
f[i] = f[i - 1] + 2 + f[j - 1]
return max(f)
class Solution {
public int longestValidParentheses(String s) {
int n = s.length();
if (n < 2) {
return 0;
}
int[] f = new int[n + 1];
int ans = 0;
for (int i = 2; i <= n; ++i) {
if (s.charAt(i - 1) == ')') {
if (s.charAt(i - 2) == '(') {
f[i] = f[i - 2] + 2;
} else {
int j = i - f[i - 1] - 1;
if (j > 0 && s.charAt(j - 1) == '(') {
f[i] = f[i - 1] + 2 + f[j - 1];
}
}
ans = Math.max(ans, f[i]);
}
}
return ans;
}
}
class Solution {
public:
int longestValidParentheses(string s) {
int n = s.size();
if (n < 2) {
return 0;
}
int f[n + 1];
memset(f, 0, sizeof(f));
for (int i = 2; i <= n; ++i) {
if (s[i - 1] == ')') {
if (s[i - 2] == '(') {
f[i] = f[i - 2] + 2;
} else {
int j = i - f[i - 1] - 1;
if (j && s[j - 1] == '(') {
f[i] = f[i - 1] + 2 + f[j - 1];
}
}
}
}
return *max_element(f, f + n + 1);
}
};
func longestValidParentheses(s string) (ans int) {
n := len(s)
if n < 2 {
return 0
}
f := make([]int, n+1)
for i := 2; i <= n; i++ {
if s[i-1] == ')' {
if s[i-2] == '(' {
f[i] = f[i-2] + 2
} else {
j := i - f[i-1] - 1
if j > 0 && s[j-1] == '(' {
f[i] = f[i-1] + 2 + f[j-1]
}
}
ans = max(ans, f[i])
}
}
return
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
public class Solution {
public int LongestValidParentheses(string s) {
int n = s.Length;
if (n < 2) {
return 0;
}
int[] f = new int[n + 1];
int ans = 0;
for (int i = 2; i <= n; ++i) {
if (s[i - 1] == ')') {
if (s[i - 2] == '(') {
f[i] = f[i - 2] + 2;
} else {
int j = i - f[i - 1] - 1;
if (j > 0 && s[j - 1] == '(') {
f[i] = f[i - 1] + 2 + f[j - 1];
}
}
ans = Math.Max(ans, f[i]);
}
}
return ans;
}
}
function longestValidParentheses(s: string): number {
const n = s.length;
const f: number[] = new Array(n + 1).fill(0);
for (let i = 2; i <= n; ++i) {
if (s[i - 1] === ')') {
if (s[i - 2] === '(') {
f[i] = f[i - 2] + 2;
} else {
const j = i - f[i - 1] - 1;
if (j && s[j - 1] === '(') {
f[i] = f[i - 1] + 2 + f[j - 1];
}
}
}
}
return Math.max(...f);
}