天天看點

LeetCode習題集-最長有效括号

文章目錄

    • 題目
    • 我的答案
    • 官方答案了解

題目

題目:給定一個隻包含 ‘(’ 和 ‘)’ 的字元串,找出最長的包含有效括号的子串的長度。

示例 1:

  輸入: “(()”

  輸出:2

  解釋:最長有效括号子串為 “()”。

示例 2:

  輸入:")()())"

  輸出:4

  解釋:最長有效括号子串為 “()()”。

對題目的了解:

  在一段字元串内需要滿足兩個條件即有效字元串:

  1: “(” 和 “)” 的數量相等。

  2: “(” 出現在對應 “)” 的前面。

  例如:"()(())" 是一個有效字元串,    “)(” 則不是(不滿足條件2)

我的答案

暴力破解法:

了解了題目之後可以知道:有效字元串肯定已 “(” 開頭。

1 是以我們第一個循環先找出該以 “(” 開始的索引位置

i

2 再從

i

開始第二層循環計算之後的字元串是否滿足有效字元串

3 當 “(” 等于 “)” 的時候就是一個有效字元串,與length比較記錄最大值

4 當 “)” 的數量比 “(” 的數量多了則肯定無法構成有效字元串了,退出第二層循環

5 繼續第一層循環找下一個以 “(” 開始的索引位置

i

public int longestValidParentheses(String s) {
    int maxLength = 0;
    // 開始計算的索引為i
    for (int i = 0; i < s.length(); i++) {
        if (s.charAt(i) == '(') {
            int left = 1;  // ( 的數量
            int right = 0;  // ) 的數量
            for (int j = i + 1; j < s.length(); j++) {
                if (s.charAt(j) == ')') {
                    right++;
                } else {
                    left++;
                }
                // 如果 ( 和 ) 的數量相等,則記錄下長度
                if (left == right) {
                    maxLength = Math.max(maxLength, left * 2);
                }
                // 如果 ) 的數量比 ( 要多, 則退出
                if (left < right) {
                    break;
                }
            }
        }
    }
    return maxLength;
}
           

執行結果:

LeetCode習題集-最長有效括号

呃呃,有點慢!别急,看下面動态規劃來解題!

官方答案了解

動态規劃:

有效字元串一定是以 “)” 結束的,其倒數第二個字元一定是 “)” 或者 “(”

定義

dp[i]

表示以下标

i

字元結尾的最長有效括号的長度。

  當字元串以 “()” 結尾時:dp[i]的狀态由dp[i−2]的狀态決定

  加上本身的"()",有:

dp[i]=dp[i−2]+2

  當字元串以 “))” 結尾時:字元串一定是"###(***)“的形式

  此時dp[i]的狀态由”***“也就是dp[i−1]的狀态和”###“也就是dp[i−dp[i−1]−2]的狀态決定

  加上本身的”()",有:

dp[i]=dp[i−1]+dp[i−dp[i−1]−2]+2

于是得到代碼:

public int longestValidParentheses(String s) {
    int maxans = 0;
    int dp[] = new int[s.length()];
    for (int i = 1; i < s.length(); 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] + ((i - dp[i - 1]) >= 2 ? dp[i - dp[i - 1] - 2] : 0) + 2;
            }
            maxans = Math.max(maxans, dp[i]);
        }
    }
    return maxans;
}
           

執行結果:

LeetCode習題集-最長有效括号

這速度,牛逼不牛逼!