先看一眼题:
总觉得用暴力解法+debug一定能出答案,只差那么临门一脚,结果这一脚足足浪费了两天时间,应该做不出来就看答案的!
先总结一下我原来的思路吧:
//32.最长有效括号
//难点:()(()的结果是2,不是4 同时要满足(()的结果是2,而不是0
//难点:同时满足()(()的结果是2,()(())的结果是6,而不能是4
public class Solution32 {
public static int longestValidParentheses(String s) {
int sum = 0;
int maxSum = 0;
Stack stack = new Stack();
char pre = '@';
for (int i = 0; i < s.length();i++ ) {
if (s.charAt(i) == '(') {
stack.push('(');
} else if (s.charAt(i) == ')') {
try{
pre= (char) stack.pop();
sum+=2;
boolean boo=false;//boo用于判断当前位置之后是不是都只有左括号
int k;
for(k=i+1;k<s.length();k++){
if(s.charAt(k)!='(') break;
}
if(k==s.length()){
boo=true;
}
if((i+1==s.length()||boo)&&!stack.empty()){
//透支减二法,无法适用于特殊情况:从第一个右括号开始(该右括号前面必须有若干左括号),后面全部都是一个左括号一个右括号的情况
//()(()、()((())、()((()())
//(()()
sum-=2;
//判断是否为特殊情况
//首先找到第一个右括号
int j;
Stack specialStack = new Stack();
for(j = 0 ; j < s.length() && s.charAt(j)!=')' ; j++){
specialStack.push(s.charAt(j));
}
//判断这个右括号前面有没有左括号
if(specialStack.empty()){
//如果没有左括号,则找到第一个左括号
for(;j<s.length()&&s.charAt(j)!='(';j++){}
//然后找到第一个右括号
for(;j<s.length()&&s.charAt(j)!=')';j++){}
}
//判断是不是一个左一个右的循环
boolean yes = true;
j++;
while (j<s.length()){
if(!s.substring(j,j+2).equals("()")){
yes=false;
break;
}
j+=2;
}
if(yes)
sum+=2;
}
}catch (Exception e){
//())的情况和()))的情况:当前子串sum应该=2
//)))的情况:当前子串sum应该=0
if(pre=='('){
sum=0;
}else if(pre=='@'){
sum=0;
}
pre='@';
}
}
if (sum > maxSum)
maxSum = sum;
}
return maxSum;
}
}
看了答案,正确思路应该是动态规划。
根据动态规划思路写代码:
//动态规划法
public static int longestValidParentheses_right1(String s){
//两两检查,如果是()的形式,的dp[i]=dp[i-2]+2
// 如果是()的形式,则寻找当前最长子串前面有没有可以匹配的左括号
int[] dp = new int[s.length()];//初值都为0
int max = 0;
for(int i = 1 ; i < s.length() ; i++){
if(s.charAt(i-1)=='('&&s.charAt(i)==')'){
if(i==1)
dp[i]=2;
else
dp[i]=dp[i-2]+2;
}
if(s.charAt(i-1)==')'&&s.charAt(i)==')'){
//看看i-1为截止点的最长子串的前面一个位置是不是(,如果是的话,说明可以找到一个正确的(来匹配当前的)
if(i-1-dp[i-1]<0){
//())的情况
dp[i]=0;
}else if(s.charAt(i-1-dp[i-1])=='(')
//( ) ( ( ) )
//0 2 0 0 2 6
dp[i]=dp[i-1]+dp[i-1-dp[i-1]-1 < 0 ? 0 : i-1-dp[i-1]-1]+2;
}
if(dp[i]>max)
max=dp[i];
}
return max;
}