1. 程式人生 > >32-最長有效括號

32-最長有效括號

Description

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

Example 1:

Input: "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()"

Example 2:

Input: ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()"

問題描述
給定只包含’(‘和’)’的字串,找出最長的合法的括號子串。

問題分析

動態規劃

狀態為dp[i], 表示以s.charAt(i)結尾的字串可以包含的最長的合法括號子串的長度

轉換
s.charAt(i) = ‘)’(由狀態的定義,我們知道s.charAt(i)必須為’)’)
若s.charAt(i - 1) = ‘(‘, dp[i] = dp[i - 2] + 2
若s.charAt(i - 1) = ‘)’ 並且 s.charAt(i - dp[i - 1] -1) = ‘(‘, dp[i] = dp[i - dp[i - 1] - 2] + 2 + dp[i - 1]

可以看看這個例子
s = “( )( ( ) )”
s.charAt(5) = ‘)’, s.charAt(4) = ‘)’且s.charAt(5 - 2 - 1) = ‘(‘, dp[5] = dp[4] + 2 + dp[5 - 2 - 2] = dp[4] + 2 + dp[1] = 2 + 2 + 2 = 6

解法1(動態規劃)

class Solution {
    public int longestValidParentheses(String s) {
        int len = s.length(), maxlen = 0;
        int
[] dp = new int[len]; for(int i = 1;i < len;i++){ if(s.charAt(i) == ')'){ if(s.charAt(i - 1) == '('){ dp[i] = (i >= 2 ? dp[i - 2] : 0) + 2; }else if(i - dp[i - 1] > 0 && s.charAt(i - dp[i - 1] - 1) == '('){ dp[i] = dp[i - 1] + 2 + ((i - dp[i - 1]) >= 2 ? dp[i - 2 - dp[i - 1]] : 0); } maxlen = Math.max(maxlen, dp[i]); } } return maxlen; } }

解法2(stack)

class Solution {
    public int longestValidParentheses(String s) {
        Stack<Integer> stack = new Stack();
        stack.push(-1);
        int maxlen = 0;

        for(int i = 0;i < s.length();i++){
            if(s.charAt(i) == '('){
                stack.push(i);
            }else{
                stack.pop();
                if(!stack.isEmpty())    maxlen = Math.max(maxlen, i - stack.peek());
                else                    stack.push(i);
            }
        }

        return maxlen;
    }
}

解法3

public class Solution {
    public int longestValidParentheses(String s) {
        int left = 0, right = 0, maxlength = 0;
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == '(') {
                left++;
            } else {
                right++;
            }
            if (left == right) {
                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 (left == right) {
                maxlength = Math.max(maxlength, 2 * left);
            } else if (left >= right) {
                left = right = 0;
            }
        }
        return maxlength;
    }
}