问题描述:
给定一个只包含 '('
和 ')'
的字符串,找出最长的包含有效括号的子串的长度。
示例 1:
输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"
示例 2:
输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-valid-parentheses
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
大体思路:
定义dp[i] 为以 i 结尾的最长有效括号长度。
转移函数如下:
为了简化逻辑,上述公式并未考虑溢出的情况。
第一种情况当前结点为左括号,以其结尾无论如何也构不成有效括号,值为0;
第二种情况,形如“(())()”的当前结点为最后一个元素的情况,当前结点为右括号,前一个为左括号,其正好能组成一对,因此等于i - 2结尾的长度加2;
第三种情况形如“()(()())”的当前结点为最后一个元素的情况,当前结点为右括号,其前一个结点也为右括号,s[i - dp[i - 1] - 1]为以s[i - 1]结尾的最长有效括号的前一个元素,该元素为左括号时就可以和s[i]的右括号组成一对,因此结果为dp[i - 1] 2 dp[i - dp[i - 1] - 2]。
第四种情况形如“)()())”的当前结点为最后一个元素的情况,s[i - dp[i - 1] - 1]不能和s[i]组成一对,因此以当前结点结尾的最长有效长度为0。
实现代码如下:
代码语言:javascript复制class Solution {
public int longestValidParentheses(String s) {
int N = s.length();
int[] dp = new int[N];
int max = 0;
for(int i = 1; i < N; i ){
if(s.charAt(i) == '('){
continue;
}
if(s.charAt(i - 1) == '('){
dp[i] = i - 2 < 0 ? 2 : 2 dp[i - 2];
}else if(i - dp[i - 1] - 1 >= 0 && s.charAt(i - dp[i - 1] - 1) == '('){
dp[i] = dp[i - 1] 2;
dp[i] = i - dp[i - 1] - 2 < 0 ? 0 : dp[i - dp[i - 1] - 2];
}
max = Math.max(max, dp[i]);
}
return max;
}
}