32. 最长有效括号
问题描述:
给定一个只包含 ‘(’ 和 ‘)’ 的字符串,找出最长的包含有效括号的子串的长度。
题目链接:https://leetcode-cn.com/problems/longest-valid-parentheses/
示例1:
输入: “(()”
输出: 2
解释: 最长有效括号子串为 “()”
示例2:
输入: “)()())”
输出: 4
解释: 最长有效括号子串为 “()()”
思路1(暴力破解法):
在这种方法中对字符串中的每个偶数长度的字符串,都进行检测是否是一个有效的括号子串,检测方法使用栈的方法。因为遍历了所有偶数长度字串,所以时间复杂度太高,LeetCode上超时。
代码如下:
//判断子字符串是不是有效括号串
private boolean isValid(String s) {
Stack<Character> stack = new Stack<>();
for (int i = 0;i < s.length(); i++) {
if (s.charAt(i) == '(') {
stack.push(s.charAt(i));
} else if (!stack.empty() && stack.peek() == '(') {
stack.pop();
}else {
return false;
}
}
return stack.empty();
}
//遍历所有子字符串,对所有字符串进行判断
public int longestValidParentheses(String s) {
if (s == null && s.length() == 0)
return 0;
int max = 0;
for (int i = 0;i < s.length(); i++) {
for (int j = i+ 2; j <=s.length(); j+=2) {
if (isValid(s.substring(i , j))){
max = Math.max(max , j - i);
}
}
}
return max;
}
思路2(利用辅助栈判断):
与找到每个可能的子字符串后再判断它的有效性不同,我们可以用栈在遍历给定字符串的过程中去判断到目前为止扫描的子字符串的有效性,同时能的都最长有效字符串的长度。我们首先将 -1−1 放入栈顶。
- 如果当前字符是
(
, 直接把当前字符入栈 - 弹出栈顶元素。如果栈为空,就把当前元素入栈。若不为空,则把当前元素索引和栈顶索引做差,记录最大值。
- 返回最大值即可
代码如下
public int longestValidParentheses2(String s) {
if (s == null || s.length() <= 1)
return 0;
int max = 0;
int dp[] = new int[s.length()];
for (int i = 1;i < s.length();i++) {
if (s.charAt(i) == ')') {
if (i - dp[i - 1] - 1 >= 0 && s.charAt(i - dp[i - 1] -1) == '(')
dp[i] = dp[i - 1] + 2;
if (i - dp[i] >= 0)
dp[i] += dp[i - dp[i]];
}
}
return max;
}
思路3 动态规划:
我们定义一个dp[]
数组,其中第i个元素代表当前下标为i的字符串结尾的最长有效子字符串的长度。
因为有效子字符串必定是以)
结尾的,所以以(
对应的字符下标对应的dp位置上全部先赋值为0。
- 如果当前字符串是
)
,那么如果s[i - dp[i-1] - 1] = '('
,也就是说第i
个字符和第i-dp[i-1]-1
字符匹配,那么dp[i-1]
就可以扩展,即dp[i] = dp[i-1] + 2
。 - 对
dp[i - dp[i]]
进行合并,把之前的有效括号串合并进来
代码如下:
public int longestValidParentheses2(String s) {
if (s == null || s.length() <= 1)
return 0;
int max = 0;
int dp[] = new int[s.length()];
for (int i = 1;i < s.length();i++) {
if (s.charAt(i) == ')') {
if (i - dp[i - 1] - 1 >= 0 && s.charAt(i - dp[i - 1] -1) == '(')
dp[i] = dp[i - 1] + 2;
if (i - dp[i] >= 0)
dp[i] += dp[i - dp[i]];
}
}
return max;
}