文章目錄
-
- 題目
- 我的答案
- 官方答案了解
題目
題目:給定一個隻包含 ‘(’ 和 ‘)’ 的字元串,找出最長的包含有效括号的子串的長度。
示例 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;
}
執行結果:

呃呃,有點慢!别急,看下面動态規劃來解題!
官方答案了解
動态規劃:
有效字元串一定是以 “)” 結束的,其倒數第二個字元一定是 “)” 或者 “(”
定義
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;
}
執行結果:
這速度,牛逼不牛逼!