LeetCode-32. Longest Valid Parentheses

来源:互联网 发布:js防水涂料刷几遍 编辑:程序博客网 时间:2024/06/01 18:42
一、题目描述

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

For "(()", the longest valid parentheses substring is "()", which has length = 2.

Another example is ")()())", where the longest valid parentheses substring is"()()", which has length = 4.

二、思路

求解字符串中合法括号对的最大长度,LeetCode论坛中给出了四种做法,这里对每种算法做简单的分析。

1.暴力求解

判断源字符串s中任一长度为2的倍数的字符子串的合法性,如果合法,则计算字符子串的长度,并计算最大长度。时间复杂度为O(N^3),超时。

public int longestValidParentheses(String s) {        
        if(s==null || s.length()<=1)            return 0;        int maxLength=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)))                    maxLength=Math.max(maxLength,j-i);            }        }        return maxLength;    }    private boolean isValid(String s){       Stack<Character> stack=new Stack<Character>();        for(int i=0;i<s.length();i++){            if(s.charAt(i)=='(')                stack.push('(');            else if(!stack.isEmpty()){                stack.pop();            }else{                return false;            }        }        return stack.isEmpty();    }
2.利用动态规划求解(通过)
首先构建动态数组dp,数组的长度为字符串的长度,索引为x的数组内容表示的是从字符串s的0-x子串中合法括号对的个数,填充数组主要是寻找s中的字符')'(一个完整的括弧对必然以右括弧结束),并判断以下两种情况
(1).如果dp[i]==')'&&dp[i-1]=='(',这样正好构成一个完整的括弧对,又因为dp[i-2]可能也是一个完整括弧对的结尾,因此,dp[i]=dp[i-2]+2.。这里其实只处理了()()()这种情况,例如:对于()(()),dp[4]=2,无法包含最前面的括弧对。
(2)如果dp[i]==')'&&dp[i-1]==')',因为dp[i-1]有可能恰好是一个完整括弧对的结尾,因此需要判断这个完整括弧对的前一个字符s.charAt(i-dp[I-1]-1)是否是做括弧,如果恰好是左括弧,则正好和dp[i]相对应,这时还需要加上dp[i-dp[i-1]-2],这里就是对(1)中例子的补充,dp[5]=6.
    public int longestValidParentheses(String s) {
if(s==null || s.length()<=1)            return 0;        int maxLength=0;        int[] dp=new int[s.length()];        for(int i=1;i<s.length();i++){            if(s.charAt(i)==')'){                if(s.charAt(i-1)=='('){                    dp[i]=(i-2>0?dp[i-2]:0)+2;                }else if(s.charAt(i-1)==')'){                    if(i-dp[i-1]>0 && s.charAt(i-dp[i-1]-1)=='(')                        dp[i]=dp[i-1]+((i-dp[i-1])>=2?dp[i-dp[i-1]-2]:0)+2;                }                maxLength=Math.max(maxLength,dp[i]);            }        }        return maxLength;
}
3.利用栈来处理(通过)
维护一个窗口,左端为变量left,右端为循环变量i,逐个扫描字符串s中的字符,如果碰到'(',将压入栈中;如果碰到‘)’,首先判断当前栈是否为空,如果栈为空,则将left=i+1(这里不能单纯的left++,比如())这种情况);如果栈不为空,则弹出栈顶的元素,再次判断此时栈是否为空,如果为空说明从left到i没有括弧嵌套;如果不为空则说明存在括弧嵌套这种情况。
public int longestValidParentheses(String s) {
if(s==null || s.length()<=1)            return 0;        LinkedList<Integer> stack=new LinkedList<Integer>();        int left=0;        int maxLength=0;        for(int i=0;i<s.length();i++){            if(s.charAt(i)=='(')                stack.add(i);            else{                if(stack.size()==0)                    left=i+1;                else{                    stack.pollLast();                    if(stack.size()==0)                        maxLength=Math.max(maxLength,i-left+1);                    else                                                maxLength=Math.max(maxLength,i-stack.peekLast());                }            }        }        return maxLength;
}
4.通过左右扫描字符串实现(我这里测试超时)
public int longestValidParentheses(String s) {
int left=0,right=0;        int maxLength=0;        for(int i=0;i<s.length();i++){            if(s.charAt(i)=='(')                left++;            else                right++;            if(right==left)                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(right==left)                maxLength=Math.max(maxLength,left*2);            else if(left>=right)                left=right=0;                        }        return maxLength;
}








0 0
原创粉丝点击