思路:
找出有效括号并且是最长的有效括号
dp[i]表示以i结尾的括号最长是多少
然后从1开始 因为从0位置不管是左括号还是右括号都是无法形成一个完成的括号。所以dp[0]=0;
当i=1时候,判断括号是否是)如果不是那么无法结尾,跳过。如果是的。先找出上一个有效的。代码如下:
class Solution {
public static int longestValidParentheses(String str) {
if (str == null || str.equals("")) {
return 0;
}
char[] chas = str.toCharArray();
int[] dp = new int[chas.length];
int pre = 0;
int res = 0;
for (int i = 1; i < chas.length; i++) {
if (chas[i] == ')') {
// pre是,当前i位置的), 应该找哪个位置的左括号
pre = i - dp[i - 1] - 1;
if (pre >= 0 && chas[pre] == '(') {
dp[i] = dp[i - 1] + 2 + (pre > 0 ? dp[pre - 1] : 0);
}
}
res = Math.max(res, dp[i]);
}
return res;
}
}
-
输入检查:
- 如果输入字符串为空或长度为0,直接返回0。
-
字符数组转换和动态规划数组初始化:
- 将字符串转换为字符数组
chas
,以便逐字符处理。 - 创建一个动态规划数组
dp
,其中dp[i]
表示以索引i
结尾的最长有效括号子串的长度。
- 将字符串转换为字符数组
-
遍历字符数组:
- 从索引1开始遍历字符数组(因为单个字符无法形成有效括号)。
- 对于每个字符,如果是右括号
)
:- 计算与当前右括号匹配的左括号的位置
pre
,pre
的计算公式为i - dp[i - 1] - 1
。 - 检查
pre
是否有效(pre >= 0
)且chas[pre]
是否为左括号(
。 - 如果条件满足,更新
dp[i]
的值,dp[i] = dp[i - 1] + 2 + (pre > 0 ? dp[pre - 1] : 0)
。dp[i - 1]
是以i-1
位置结尾的有效括号子串长度。+2
是因为当前()
增加了2个字符的长度。(pre > 0 ? dp[pre - 1] : 0)
是因为如果pre
前面还有有效括号子串,需要加上它的长度。
- 计算与当前右括号匹配的左括号的位置
-
更新结果:
- 在每次更新
dp[i]
后,使用res = Math.max(res, dp[i])
更新最长有效括号子串的长度。
- 在每次更新
-
返回结果:
- 返回记录的最长有效括号子串的长度
res
。
- 返回记录的最长有效括号子串的长度