Longest Valid Parentheses

https://leetcode.com/problems/longest-valid-parentheses/

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.

解题思路:

这是一道比较难的题目,我想了半天也没做出来,参考了其他网友的解法。

这道题类似的Valid Parentheses之前做过,使用了栈的数据结果。思路是,遇到左括号push,遇到右括号pop,如果此时stack空就false,或者整个字符串遍历结束后,stack还有元素就false。

这道题和上面差不多,但是关键在于,如何记录最长的长度?比如"()(())",遍历到最后一个)时候,如何知道这时的长度是从第一位开始,还是第三位?

下面的解法有两处非常巧妙。

第一,用了一个start变量,维护当前位置上的最长长度,可能的左边界。这个边界仅仅在遇到一个右括号,弹出栈内的左括号后,发现栈为空的时候发生。为什么?因为这说明当前已经配对完毕了,从start一直到当前的i,都可以连成一片,中间没有间隔。所以这是长度就是i - start + 1。

第二,遇到左括号push的时候,不是将'('入栈,而是将他的下标push。这样遇到一个右括号,弹出栈内的左括号后,如果stack不为空,就可以先用i - stack.peak()记录当前配对的长度。实际上这个stack.peek()就是之前弹出左括号的前一个下标,所以长度不需要+1了。

如果遇见右括号,而且栈为空呢?说明这个右括号纯粹是多余的,而且无法找到左括号配对了。它将隔断后面所有的配对,所以这时start必须置为i+1。

public class Solution {

    public int longestValidParentheses(String s) {

        int length = 0, maxLength = 0, start = 0;;

        Stack<Integer> stack = new Stack<Integer>();

        

        for(int i = 0; i < s.length(); i++) {

            if(s.charAt(i) == '(') {

                stack.push(i);

            }

            if(s.charAt(i) == ')') {

                if(stack.empty()) {

                    start = i + 1;

                } else {

                    stack.pop();

                    if(!stack.empty()) {

                        length = i - stack.peek();

                        maxLength = Math.max(length, maxLength);

                    }else {

                        length = i - start + 1;

                        maxLength = Math.max(length, maxLength);

                    }

                }

            }

        }

        return maxLength;

    }

}

这道题的思路还是非常巧妙的,有所跳跃,又基于平常的解法,面试的时候如果遇到,还是比较能看出水平的。

update 2015/05/29:

二刷,一个dp的解法,和Valid Parentheses 里的解法一样。

public class Solution {

    public int longestValidParentheses(String s) {

        if(s == null || s.length() == 0) {

            return 0;

        }

        int[] dp = new int[s.length()];

        dp[0] = 0;

        for(int i = 1; i < s.length(); i++) {

            if(s.charAt(i) == '(') {

                dp[i] = 0;

            } else {

                int left = i - 1 - dp[i - 1];

                if(left < 0) {

                    dp[i] = 0;

                } else {

                    if(s.charAt(left) != '(') {

                        dp[i] = 0;

                    } else {

                        if(left > 0) {

                            dp[i] = dp[i - 1] + 2 + dp[left - 1];

                        } else {

                            dp[i] = dp[i - 1] + 2;

                        }

                    }

                }

            }

        }

        int max = 0;

        for(int i = 0; i < dp.length; i++) {

            max = Math.max(max, dp[i]);

        }

        return max;

    }

}

 

你可能感兴趣的:(long)