32. 最長有效括號(C++)---動態規劃解題

題目詳情

給定一個只包含 '(' 和 ')' 的字符串,找出最長的包含有效括號的子串的長度。

示例 1:

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

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



——題目難度:困難


 





分析

題目所說的 “最長的包含有效括號的子串” 的意思是該子串裏不允許有 沒有成爲"(...)",也就是沒有匹配的括號。

使用動態規劃解題一般有如下3個步驟:

  1. 確定狀態
    - 研究最優策略的最後一步
    - 化爲子問題
  2. 確定狀態轉移方程
    - 根據子問題定義得到
  3. 確定邊界條件 初始情況

接下來用以上3個步驟來分析題目:
1.確定狀態:這裏定義一個dp數組,dp[i]表示以下標 i 爲字符結尾的最長有效字符串的長度(注意:這裏是必須將s[i]這個字符包含在內的!)
2.確定狀態轉移方程:當遍歷s串時,如果是s[i]='(',就不用考慮,因爲不可能構造合法括號;
當s[i]=')'時,分以下兩種情況:
①s[i-1]='('時,也就是字符串形如"...()",那麼dp[i] = dp[i-2] + 2
②s[i-1]=')'時,也就是字符串形如"...))"的時候,這種情況下,如果前面要和 s[i] 組成有效括號對的字符,即形如"( (....) )",這樣的話,就要求 s[i - 1] 位置必然是有效的括號對,否則 s[i] 無法和前面對字符組成有效括號對。

如果倒數第二個')'是一個有效字符串(記爲subs),那麼我們只需要判斷 subs 前面的一個符號是不是'(',如果是'(' 則可以說明 此時的最長有效括號的長度爲:subs 的長度(dp[i-1]) 加上字符串 subs 前面的有效字符串(dp[i - dp[i - 1] - 2]) 加上 2,這時候字符串可以形如"(...)((...))" 。
3.確定邊界條件 初始情況:

  • i-2 有可能小於0而導致越界,這時候就是隻有(),前面記爲0就好了
  • i - dp[i - 1] - 2 和 i - dp[i - 1] - 1 都有可能出現小於0的越界問題,如果越界了 同樣 記爲0即可


 




-解題代碼

class Solution {
public:
    int longestValidParentheses(string s) {
    	int len = s.size();
    	int ans = 0;
        vector<int> dp(len);
        
        for(int i = 1; i < len; i++)
        {
        	if (s[i] == ')') {
        		if (s[i-1] == '(') {
        			dp[i] = (i - 2 >= 0 ?  dp[i-2] : 0) + 2;
        		} else if (i - dp[i-1] - 1 >= 0 && s[i-dp[i-1]-1] == '(') {
        			dp[i] = (i - dp[i-1] - 2 >=0 ? dp[i-dp[i-1]-2] : 0) + dp[i-1] + 2;
        		}
        	}
        	
        	ans = max(ans, dp[i]);
        }
        		
        return ans;		
    }
};

結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章