32-最長有效括號
阿新 • • 發佈:2019-02-16
Description
Given a string containing just the characters ‘(’ and ‘)’, find the length of the longest valid (well-formed) parentheses substring.
Example 1:
Input: "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()"
Example 2:
Input: ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()"
問題描述
給定只包含’(‘和’)’的字串,找出最長的合法的括號子串。
問題分析
動態規劃
狀態為dp[i], 表示以s.charAt(i)結尾的字串可以包含的最長的合法括號子串的長度
轉換
s.charAt(i) = ‘)’(由狀態的定義,我們知道s.charAt(i)必須為’)’)
若s.charAt(i - 1) = ‘(‘, dp[i] = dp[i - 2] + 2
若s.charAt(i - 1) = ‘)’ 並且 s.charAt(i - dp[i - 1] -1) = ‘(‘, dp[i] = dp[i - dp[i - 1] - 2] + 2 + dp[i - 1]
可以看看這個例子
s = “( )( ( ) )”
s.charAt(5) = ‘)’, s.charAt(4) = ‘)’且s.charAt(5 - 2 - 1) = ‘(‘, dp[5] = dp[4] + 2 + dp[5 - 2 - 2] = dp[4] + 2 + dp[1] = 2 + 2 + 2 = 6
解法1(動態規劃)
class Solution {
public int longestValidParentheses(String s) {
int len = s.length(), maxlen = 0;
int [] dp = new int[len];
for(int i = 1;i < len;i++){
if(s.charAt(i) == ')'){
if(s.charAt(i - 1) == '('){
dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2;
}else if(i - dp[i - 1] > 0 && s.charAt(i - dp[i - 1] - 1) == '('){
dp[i] = dp[i - 1] + 2 + ((i - dp[i - 1]) >= 2 ? dp[i - 2 - dp[i - 1]] : 0);
}
maxlen = Math.max(maxlen, dp[i]);
}
}
return maxlen;
}
}
解法2(stack)
class Solution {
public int longestValidParentheses(String s) {
Stack<Integer> stack = new Stack();
stack.push(-1);
int maxlen = 0;
for(int i = 0;i < s.length();i++){
if(s.charAt(i) == '('){
stack.push(i);
}else{
stack.pop();
if(!stack.isEmpty()) maxlen = Math.max(maxlen, i - stack.peek());
else stack.push(i);
}
}
return maxlen;
}
}
解法3
public class Solution {
public int longestValidParentheses(String s) {
int left = 0, right = 0, maxlength = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
left++;
} else {
right++;
}
if (left == right) {
maxlength = Math.max(maxlength, 2 * right);
} else if (right >= left) {
left = right = 0;
}
}
left = right = 0;
for (int i = s.length() - 1; i >= 0; i--) {
if (s.charAt(i) == '(') {
left++;
} else {
right++;
}
if (left == right) {
maxlength = Math.max(maxlength, 2 * left);
} else if (left >= right) {
left = right = 0;
}
}
return maxlength;
}
}