动态规划算法-06Longest Valid Parentheses问题
生活随笔
收集整理的這篇文章主要介紹了
动态规划算法-06Longest Valid Parentheses问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最長合法匹配子串長度(動態規劃解法)
- 簡述
- 給定一個只包含"(",")"的字符串,是判斷一個最長的且能完全匹配的子串的長度。
- 看到這種最有解問題,本能應該想到是動態規劃解題。(且只求最值不求序列的可以遞歸實現)
- 這是LeetCode動態規劃類別的一道題。
- 問題描述
- 給定一個字符串,只包含"(“和”)",規定一個"(“必須匹配一個”)",找一個最長的可以完全匹配的子串長度。
- 如"((()“答案為2,”(()))"答案為4。
- 問題分析
- 如何找到最優子結構以及狀態轉移函數和邊界是動態規劃的核心思路。
- 如何用已知最優解去構造當前最優解,這就是這題的思路。很明顯,這是要填一個一維表。
- 不妨定義F(n)為以第n個字符為結尾的最大子串的長度。
- 可以簡單分析一下兩種情況。
- 第n個字符是"(",不存在某個匹配子串結尾是"(",dp記為0。
- 第n個字符是")",此時需要看前面一個字符。
- 若s[n-1]為"(",那么兩者剛好匹配,最長長度為這兩者的長度2加上n-2為結尾的最長子串長度。(簡單理解,剛好銜接)
- 若s[n-1]為")",那么就要去看以這個右括號為結尾的最長子串的前一個字符j是什么,如果j是"(",那么剛好,這個"(“和n位置上的”)“包裹了一個最長子串,這是最長子串就是包裹的這個子串加以包裹起始的”(“前一個字符為結尾的字符串長度,此長度為2+dp[n-1]+dp[n-1-dp[n-1]-1];如果j是”)",銜接斷開,dp[n]保持0即可。
- 可以簡單分析一下兩種情況。
- F(n)邊界、狀態轉移函數如下。
- F(n) = 0 ,s[n]="("
- F(n) = F(n-2) + 2 ,s[n-1]="("
- F(n) = 0 ,s[n-1]=")",s[i-1- dp[i - 1]]=")"
- F(n) = 2 + F[i - 1] + F[i-1-dp[i-1]-1] ,s[n-1]=")",s[i-1- dp[i - 1]]="("
- 代碼
- 注意:Python的列表可以負號索引,需要注意控制邊界。
- 代碼使用循環填表,由底向上填表實現。(也可以遞歸實現)
- 代碼使用LeetCode答題基本格式
- class Solution:def longestValidParentheses(self, s: str) -> int:if len(s) < 2:return 0dp = [0 for i in range(len(s))]for i in range(len(s)):if s[i] == "(":passelse:if i-1 >= 0:if s[i - 1] == "(":# 此時和i號字符匹配的已經找到dp[i] = dp[i - 2] + 2else:# 此時這個右括號可能是一個合法子串的結尾也可能不是if s[i-1- dp[i - 1]] == "(" and i-1-dp[i-1] >=0:dp[i] = 2 + dp[i - 1] + dp[i-1-dp[i-1]-1]else:passreturn max(dp)
- 補充說明
- 具體代碼可以查看我的Github,歡迎Star或者Fork
- 此題為LeetCode動態規劃的一題,題號為32,難度Hard
總結
以上是生活随笔為你收集整理的动态规划算法-06Longest Valid Parentheses问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 动态规划算法-05KSum问题
- 下一篇: 机器学习-关联之Apriori算法原理及