LeetCode: Longest Valid Parentheses
问题描述
Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring.
Example1
Input: s = “(()”
Output: 2
Explanation: The longest valid parentheses substring is “()”.
Example2
Input: s = “)()())”
Output: 4
Explanation: The longest valid parentheses substring is “()()”.
Example3
Input: s = “”
Output: 0
方法思路
动态规划:
首先设置一个整型数组 dp[i] , 表示以 s[i] 结尾的连续有效括号子串的长度,从左向右遍历 s[i],可能存在以下几种情况:
- 当 s[i] == ‘(’ ,因为以 ‘(’ 结尾肯定不是有效的括号子串,所以 dp[i] = 0.
- 当 s[i] == ‘)’ 时,可能存在以下多种情况:
- 检验 s[i-1],当 s[i-1] == ‘(’ 时,形成了 “()”,括号子串的有效长度至少为2,进一步地,在已知 dp[i] == 2 的情况下,还需要检验 s[i-2] 是否存在
- 如果 s[i-2] 存在并且 dp[i-2] != 0, 那么 dp[i] = dp[i-2]+2
- 如果 s[i-2] 不存在或者 dp[i-2] == 0, dp[i] = 2
- 检验 s[i-1],当 s[i-1] == ‘)’ 时, 形成了"))", 这种情况就需要先判断与 s[i-1] 匹配的括号的前一个括号是否存在
- 如果存在并且是’(’,正好与 s[i] 相匹配,则 dp[i] 至少为 dp[i-1] + 2 ,另外还需要判断与 s[i] 相匹配的 ‘(’ 的前面是否还有有效的括号子串,位置为 i (当前子串的尾部) - 1(子串尾部前一个 ‘)’ ) - dp[i-1] ( i-1 对应的最长有效子串的长度) - 1(子串首部的’(’ )
- 如果不存在,则 dp[i] = dp[i-1]+2
- 如果存在, 则 dp[i] = dp[i-1]+2+dp[i-1-dp[i-1]-1]
- 如果不存在, dp[i] == 0
- 如果存在并且是’(’,正好与 s[i] 相匹配,则 dp[i] 至少为 dp[i-1] + 2 ,另外还需要判断与 s[i] 相匹配的 ‘(’ 的前面是否还有有效的括号子串,位置为 i (当前子串的尾部) - 1(子串尾部前一个 ‘)’ ) - dp[i-1] ( i-1 对应的最长有效子串的长度) - 1(子串首部的’(’ )
- 检验 s[i-1],当 s[i-1] == ‘(’ 时,形成了 “()”,括号子串的有效长度至少为2,进一步地,在已知 dp[i] == 2 的情况下,还需要检验 s[i-2] 是否存在
栗子 “(()()))” :
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|---|---|
s | ( | ( | ) | ( | ) | ) | ) |
dp | 0 | 0 | 2 | 0 | 4 | 6 | 0 |
* 思路来自于 https://www.bilibili.com/video/BV17C4y1a7rs?from=search&seid=2289367917882798129&spm_id_from=333.337.0.0
代码如下(示例):
class Solution {
public int longestValidParentheses(String s) {
int[] dp = new int[s.length()];
for(int i = 0; i < s.length(); i++){
//If s[i] is '('
if(s.charAt(i) == '('){
dp[i] = 0;
}
//If s[i] is ')'
else{
if( i - 1 > -1){
//If s[i-1] is '(', we will get a valid parenthese "()"
if( s.charAt(i-1) == '('){
dp[i] = 2;
if( i - 2 > -1 && dp[i-2] != 0){
dp[i] = dp[i-2] + 2;
}
}
//If s[i-1] is ')', we will get "))"
else{
if( i-1-dp[i-1] > -1 && s.charAt(i-1-dp[i-1]) == '('){
if(i-1-dp[i-1]-1 > -1 && dp[i-1-dp[i-1]-1] != 0){
dp[i] = dp[i-1]+2+dp[i-1-dp[i-1]-1];
}else{
dp[i] = dp[i-1]+2;
}
}else{
dp[i] = 0;
}
}
}else{
dp[i] = 0;
}
}
}
int max = 0;
for(int i = 0; i < dp.length; i++){
if(dp[i] > max){
max = dp[i];
}
}
return max;
}
}