Idiot-maker

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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;
    }
}

 //20180927

class Solution {
    public int longestValidParentheses(String s) {
        if (s == null || s.length() == 0 || s.length() == 1) {
            return 0;
        }
        int[] dp = new int[s.length()];
        dp[0] = 0;
        int longest = 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 || s.charAt(left) == ')') {
                    dp[i] = 0;
                } else if (left == 0) {                    
                    dp[i] = i + 1;
                } else {
                    dp[i] = dp[left - 1] + i - left + 1;                    
                }
                longest = Math.max(longest, dp[i]);
            }
        }
        return longest;
    }
}

 

posted on 2015-04-05 20:07  NickyYe  阅读(180)  评论(0编辑  收藏  举报