这道题在写的时候,最开始考虑暴力求解,当然时间复杂度为O(n^3),会超时的,提交后果然超时,然后进行优化,首先想到的是用栈,奈何一时间没有解出来,看了题解,原来又是动态规划,感觉最难的就是推导动态转移方程,只能耐着性子去看了,看了一点点,然后自己有思路了,为此,把这道题写到博客中记录下来。
思路:
直接看一张图解即可,如果你还是不理解的话,可以去看看力扣该题的题解视频
也许到此你还是并未完全理解透彻,那么请有一个大致思路
1.先找自己对应的左括号下标
2.判断对应下标是否是左括号
3.判断该左括号前边是否有括号
下边是自己的代码,里边也有详细的注释,希望大家可以理解
public static int longestValidParentheses(String s) {
int len = s.length();
if (len <= 1) {
return 0;
}
char[] arr = s.toCharArray();
// 初始dp数组,数据全部默认为0,
int[] dp = new int[len];
int max = 0;
// 下标从1开始遍历,位置0,无论是左括号还是右括号对应的数值都应该是0
for (int i = 1; i < len; i++) {
if (arr[i] == '(') {
// 如果当前位置为左括号则跳过,默认就是0,不用做记录
continue;
}
// 当前位置为右括号
// 1.先找自己对应的左括号下标
// 这里比较巧的就是dp[i-1]了,如果是前边是左括号则其恰好是0,i-dp[i-1]-1恰好是前一个位置
if ( i-dp[i-1]-1 < 0 ) {
// 对应的左括号下标不存在
dp[i] = 0;
} else {
// 对应的左括号下标存在
// 2.判断对应下标是否是左括号
if ( arr[i-dp[i-1]-1] != '(' ) {
// 对应下标不是左括号
dp[i] = 0;
} else {
// 对应下标是左括号
dp[i] = 2 + dp[i-1];
// 3.判断该左括号前边是否有括号
if ( i-dp[i-1]-2 > 0 ) {
// 该左括号前边存在括号,无论前边是左括号(0)还是右括号(0/非0)均可直接相加
dp[i] += dp[i-dp[i-1]-2];
}
}
}
// 比较获取最大值
if ( max < dp[i]) {
max = dp[i];
}
}
return max;
}
已AC