leetcode32 Longest Valid Parentheses 最长括号组的长度

题目要求

原题地址:https://leetcode.com/problems...面试

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.

一个括号序列,求出其中成对括号的最大长度segmentfault

思路一:使用堆栈

这题能够参考个人另外一篇博客,这篇博客讲解了如何用堆栈判断括号序列是否能够成对。咱们能够将堆栈的思路延续到这里。每当遇到一个左括号或者是没法成对的右括号,就将它压入栈中,能够成对的括号则从栈中压出。这样栈中剩下的就是没法成对的括号的下标。这时咱们能够判断这些下标间的距离来得到最大的成对括号长度。在这里须要先遍历一遍字符串,再遍历一下非空的堆栈。数组

public int longestValidParentheses(String s) {
        Stack<Parenthese> parenthesesStack = new Stack<Parenthese>();
        for(int i = 0 ; i < s.length() ; i++){
            char symbol = s.charAt(i);
            if(symbol==')'){
                //在这里左右括号能够成对,则出栈
                if(!parenthesesStack.isEmpty() && parenthesesStack.peek().symbol=='('){
                    parenthesesStack.pop();
                    continue;
                }
            }
            //其余状况都压入栈中
            parenthesesStack.push(new Parenthese(symbol, i));
        }
        int maxLength = 0;
        int nextIndex = s.length();
        while(!parenthesesStack.isEmpty()){
            int curIndex = parenthesesStack.pop().index;
            maxLength = (nextIndex-curIndex-1)>maxLength ? nextIndex-curIndex-1 : maxLength;
            nextIndex = curIndex;
        }
        return Math.max(nextIndex, maxLength);
    }
    
    public class Parenthese{
        char symbol;
        int index;
        public Parenthese(char symbol, int index){
            this.symbol = symbol;
            this.index = index;
        }    
    }

在这里能够优化,由于使用数据结构不是必要的。咱们能够直接压入栈中下标,再从字符串中得到该下标对应的字符微信

public int longestValidParentheses_noDataStructure(String s) {
        Stack<Integer> parenthesesStack = new Stack<Integer>();
        for(int i = 0 ; i < s.length() ; i++){
            if(s.charAt(i)==')'){
                if(!parenthesesStack.isEmpty() && s.charAt(parenthesesStack.peek())=='('){
                    parenthesesStack.pop();
                    continue;
                }
            }
            parenthesesStack.push(i);
        }
        int maxLength = 0;
        int nextIndex = s.length();
        while(!parenthesesStack.isEmpty()){
            int curIndex = parenthesesStack.pop();
            int curLength = nextIndex-curIndex-1;
            maxLength = curLength>maxLength ? curLength : maxLength;
            nextIndex = curIndex;
        }
        return Math.max(nextIndex, maxLength);
    }

思路二:dynamic programming

dynamic programming 的真 奥义其实在于假设已知以前全部的结果,结合以前的结果穷尽每一种当前值可能的状况
在这道题目中,咱们假设已经知道长度为n-1字符串中,到每个下标为止的的最大的括号组长度,这些值被存储在和字符串长度等长的int数组s中,其中s的下标表明字符串的下标,s的值表明到这个字符串下标为止最长括号组长度。
那么当前第n个符号主要有如下三种状况:数据结构

  1. 当前值为‘(’,那么不管前面状况如何,当前必定是没法造成括号的,因此最大长度为0
  2. 当前值为‘)’,前一个值为‘(‘, 那么最大长度为s[n-2](若是存在的话)+ 2
  3. 当前值为‘)’,前一个值也是')',若是在i-s[i-1]-1的位置上是一个’(‘,那么最大长度为s[i-1]+2+s[i-s[i-1]-2],具体状况能够参考()(())当n=5时,不然仍旧为0

代码实现以下优化

public int longestValidParentheses_dynamicProgramming(String s) {
        int[] maxCount = new int[s.length()];
        int maxLength = 0;
        for(int i = 1 ; i<s.length() ; i++){
            if(s.charAt(i) == ')'){
                if(s.charAt(i-1)=='('){
                    maxCount[i] = (i>=2? maxCount[i-2]+2 : 2);
                    maxLength = Math.max(maxCount[i], maxLength);
                }else{
                    if(i-maxCount[i-1]-1>=0 && s.charAt(i-maxCount[i-1]-1)=='('){
                        maxCount[i] = maxCount[i-1]+2 + ((i-maxCount[i-1]-2 >= 0)?maxCount[i-maxCount[i-1]-2]:0);;
                        maxLength = Math.max(maxCount[i], maxLength);
                    }
                }
            }
        }
        return maxLength;        
    }

简化后的代码以下:this

public int longestValidParentheses_dynamicProgrammingConcise(String s) {
        int[] maxCount = new int[s.length()];
        int maxLength = 0;
        for(int i = 1 ; i<s.length() ; i++){
            if(s.charAt(i) == ')' && i-maxCount[i-1]-1>=0 && s.charAt(i-maxCount[i-1]-1)=='('){
                maxCount[i] = maxCount[i-1] + 2 + ((i-maxCount[i-1]-2>=0) ? maxCount[i-maxCount[i-1]-2] : 0);
                maxLength = Math.max(maxCount[i], maxLength);
                
            }
        }
        return maxLength;        
    }

clipboard.png
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注个人微信公众号!将会不按期的发放福利哦~spa

相关文章
相关标签/搜索