1. 程式人生 > 其它 >最長有效括號題解

最長有效括號題解

技術標籤:java

給定一個只包含 '('和 ')'的字串,找出最長有效(格式正確且連續)括號子串的長度。

示例 1:

輸入:s = "(()"
輸出:2
解釋:最長有效括號子串是 "()"
示例 2:

輸入:s = ")()())"
輸出:4
解釋:最長有效括號子串是 "()()"

這裡採用動態規劃加遞迴解決該問題

1) 有效括號字串中至少包含一對"()",因此首先遍歷字串,找到"()",如果找不到,則說明字串中沒有有效括號

2) 當找到"()"後,則找到了第一個有效括號,假設s[i][j]表示字串s的第i位到第j位為有效括號

3) 若s[i][j]為有效括號,如果s[i-1]='('並且s[j+1]=')',則s[i-1][j+1]仍然為有效括號,按照這個思路繼續往下遞迴

4)若s[i][j]為有效括號,且s[k][i-1]也為有效括號,則s[k][j]仍然為有效括號;若s[j+1][p]為有效括號,則s[i][p]仍然為有效括號

程式碼如下:

class Solution {

    /**
      查詢鄰居字串
    */
    private int searchNeighbor(String s, int i, int j, int currentLength, boolean[] path) {
        int length = s.length();
        int maxLength = currentLength;
        
        if (i > 0 && j < length - 1) {
            //若有效字串的前一位為'(',後一位為')',則找到了新的有效括號
            if (s.charAt(i - 1) == '(' && s.charAt(j + 1) == ')') {
                path[i-1] = true;
                path[j+1] = true;
                int result = searchNeighbor(s, i-1, j+1, currentLength + 2, path);
                if (result > maxLength) {
                    maxLength = result;
                }
                return maxLength;
            }
        }

        if (i > 1) {
            int pos;
            //在該有效括號之前查詢是否有相鄰的有效括號
            for (pos = i -1; pos >= 0; pos--) {
                if (!path[pos]) {
                    break;
                }
            }
            pos++;

            //找到了相鄰的有效括號,則拼接成新的有效括號
            if (pos < i) {
                int result = searchNeighbor(s, pos, j, currentLength + i - pos, path);
                if (result > maxLength) {
                    maxLength = result;
                }
            }
        }

        return maxLength;
    }


    public int longestValidParentheses(String s) {
        if (null == s || s.length() == 1) {
            return 0;
        }

        int length = s.length();
        //用一個數組記錄標記
        boolean[] path = new boolean[length];

        int maxLength = 0;
        for (int i=0; i < length -1; i++) {
            //找到了"()",則繼續遞迴遍歷
            if (s.charAt(i) == '(' && s.charAt(i+1) == ')') {
                path[i] = true;
                path[i + 1] = true;
                int result = searchNeighbor(s, i, i + 1, 2, path);
                if (result > maxLength) {
                    maxLength = result;
                }
            }
        }
        
        return maxLength;
    }
}