1. 程式人生 > >Leetcode 32. Longest Valid Parentheses--求最大連續的成對圓括號的長度,如果中間有多餘的單個圓括號則不算作連續

Leetcode 32. Longest Valid Parentheses--求最大連續的成對圓括號的長度,如果中間有多餘的單個圓括號則不算作連續

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 "()()"
import java.util.Stack;

/**
 * <p>Title: </p>
 * <p>Description: </p>
 *
 * @CreateTime 2019/1/6 14:07
 */
public class Leetcode_32_LongestValidParentheses {

    public static void main(String[] args) {
        Leetcode_32_LongestValidParentheses leetcode_32_longestValidParentheses = new Leetcode_32_LongestValidParentheses();
        System.out.println(leetcode_32_longestValidParentheses.longestValidParentheses("()(())"));//6
//        System.out.println(leetcode_32_longestValidParentheses.longestValidParentheses("((())))))()"));//6
//        System.out.println(leetcode_32_longestValidParentheses.longestValidParentheses("(((((((()"));//2
    }

    /**
     * https://leetcode.com/problems/longest-valid-parentheses/discuss/198257/12-Line-DP-O(n)-4ms
     * 8 ms. Your runtime beats 73.39 % of cpp submissions.
     *
     * @param s
     * @return
     */
    public int longestValidParentheses(String s) {
        int result = 0;
        int[] dp = new int[s.length() + 1];
        for (int i = 0; i < s.length(); i++) {
            if (s.charAt(i) == ')') {
                int pre = i - 1 - dp[i];//找到s中前面對應的'('字元的索引
                if (pre >= 0 && s.charAt(pre) == '(') {//判斷前面對應這個字元是否是'('
                    //dp[i]當前這段()組成的最大長度,dp[prev]前面這段()組成的最大長度,這兩段()中的字元無交集
                    dp[i + 1] = dp[i] + 2 + dp[pre];
                }
            }
            result = Math.max(result, dp[i + 1]);
        }
        return result;
    }

    /**
     * 錯誤的方法
     *
     * @param s
     * @return
     */
    public int longestValidParentheses3(String s) {

        if (s == null || s.length() == 0 || s.length() == 1) {
            return 0;
        }

        if (s.indexOf(")") == -1 || (!s.contains("(") && s.contains(")"))) {
            return 0;
        }
        s = s.substring(s.indexOf("("), s.length());

        Stack<Element> stack = new Stack<>();
        stack.push(new Element(0, s.charAt(0)));
        int maxLength = 0;
        for (int i = 1; i < s.length(); i++) {
            char c = s.charAt(i);
            if (!stack.empty() && stack.peek().c == '(' && c == ')') {
                stack.pop();
                maxLength += 2;
            } else {
                stack.push(new Element(i, c));
            }
        }//for

        if (stack.empty()) {
            return maxLength;
        } else {
            int index = stack.pop().index;
            if ((index == s.length() - 1 || index == 0) && stack.empty()) {
                return maxLength;
            } else if (stack.empty()) {
                return Math.max(index, maxLength - index);
            }

            if (maxLength < index) {
                maxLength = 0;
            }

            while (!stack.empty()) {
                int leftIndex = stack.pop().index;
                maxLength = Math.max(maxLength, index - leftIndex - 1);
                index = leftIndex;
                if (stack.empty()) {
                    maxLength = Math.max(maxLength, index);
                }
            }
            return maxLength;
        }
    }//longestValidParentheses

    class Element {

        int index;
        char c;

        public Element(int index, char c) {
            this.index = index;
            this.c = c;
        }
    }

    /**
     * 這只是計算出成對()的長度,也包括中間有(或)斷開不連續的子串了
     *
     * @param s //"()(()" 返回4,正確應該返回2
     * @return
     */
    public int longestValidParentheses2(String s) {

        if (s == null || s.length() == 0 || s.length() == 1) {
            return 0;
        }

        if ((s.contains("(") && !s.contains(")")) || (s.contains(")") && !s.contains("("))) {
            return 0;
        }

        Stack<Character> stack = new Stack<>();
        stack.push(s.charAt(0));
        int maxLength = 0;
        for (int i = 1; i < s.length(); i++) {
            char c = s.charAt(i);
            if (!stack.empty() && stack.peek() == '(' && c == ')') {
                stack.pop();
                maxLength += 2;
            } else {
                stack.push(c);
            }
        }//for
        return maxLength;
    }//longestValidParentheses

}//Leetcode_32_LongestValidParentheses

end