Given a string containing just the characters '('
and ')'
, return the length of the longest valid (well-formed) parentheses substring.
Example 1:
Input: s = "(()" Output: 2 Explanation: The longest valid parentheses substring is "()".
Example 2:
Input: s = ")()())" Output: 4 Explanation: The longest valid parentheses substring is "()()".
Example 3:
Input: s = "" Output: 0
Constraints:
0 <= s.length <= 3 * 104
s[i]
is'('
, or')'
.
Approach 1: Dynamic Programming
We define
When
When
- If
$s[i-1]$ is a left parenthesis, then the length of the longest valid parentheses that ends with$s[i-1]$ must be$0$ , so$f[i] = 0$ . - If
$s[i-1]$ is a right parenthesis, there are the following two cases:- If
$s[i-2]$ is a left parenthesis, then the length of the longest valid parentheses that ends with$s[i-1]$ is$f[i-2] + 2$ . - If
$s[i-2]$ is a right parenthesis, then the length of the longest valid parentheses that ends with$s[i-1]$ is$f[i-1] + 2$ , but we also need to consider whether$s[i-f[i-1]-2]$ is a left parenthesis. If it is a left parenthesis, then the length of the longest valid parentheses that ends with$s[i-1]$ is$f[i-1] + 2 + f[i-f[i-1]-2]$ .
- If
Therefore, we can get the state transition equation:
Finally, we only need to return
The time complexity is
class Solution:
def longestValidParentheses(self, s: str) -> int:
n = len(s)
f = [0] * (n + 1)
for i, c in enumerate(s, 1):
if c == ")":
if i > 1 and s[i - 2] == "(":
f[i] = f[i - 2] + 2
else:
j = i - f[i - 1] - 1
if j 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();
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();
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)
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 if j := i - f[i-1] - 1; 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;
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);
}
/**
* @param {string} s
* @return {number}
*/
var longestValidParentheses = function (s) {
const n = s.length;
const f = 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);
};