最长有效括号
题目描述:
给你一个只包含 '(' 和 ')' 的字符串,找出最长有效(格式正确且连续)括号子串的长度。
提示:
0 <= s.length <= 3*10^4
s[i] 为 '(' 或 ')'
class Solution {
private int[] result;
public int longestValidParentheses(String s) {
if(s == null) return 0;
int len = s.length();
if(len == 0) return 0;
this.result = new int[len]; // 定义 数组末尾可匹配括号连续的个数
int maxNum = 0;
// 初始化
if(len >= 2 && s.charAt(1) == ')' && s.charAt(0) == '('){
result[1] = 2;
maxNum = 2;
}
// 动态规划过程
for(int i = 2;i<len ; i++){ // 从第三个符号开始
if(s.charAt(i) == ')'){
if(s.charAt(i-1) == '('){
result[i] = result[i-2] + 2;
}else{
if(i-1 - result[i-1] >= 0 && s.charAt(i - 1 - result[i-1]) == '('){
result[i] = result[i-1] + 2 +
(i-2 - result[i-1] < 0 ? 0:result[i-2 - result[i-1]]);
}
}
}
maxNum = maxNum>result[i] ? maxNum:result[i];
}
return maxNum;
}
}
该题采用动态规划,定义动态规划数组(result)为末尾可匹配括号连续的个数
分析:
当下标i的符号为'(',其result数组下标i的值为0
当下标i的符号为')',有两种情况:
第一种,如果result数组下标为i-1开始向左边跳过其连续的可匹配括号个数(也就是result下标为i-1的值),然后其后的一位符号若为'(',
就是说明下标为i的符号和下标为i-1-result[i-1]的符号可匹配,因此result[i]需要加2,这还没完,因为我们还不知道result[i-1 - 1 - result[i-1]]
是否还有连续的可匹配括号个数,因此我们还需要加上result[i-2 - result[i-1]],该条件下的最终转移方程为:result[i] = result[i-1-result[i-1]] + 2 + result[i-2-result[i-1]]
第二种,如果result数组下标为i-1开始向左边跳过其连续的可匹配括号个数(也就是result下标为i-1的值),然后其后的一位符号若为')',
那么result[i]的直接为0,因为末尾可匹配括号的连续个数为0
这里需要每次保存最大的长度,也就是每次比较for遍历的下标为i的result值