Leetcode_32.最长有效括号

方法一:动态规划

解题思路:

结合题目,有最长这个字眼,可以考虑尝试使用动态规划进行分析。这是一个最值型动态规划的题目。
动态规划题目分析的 4 个步骤:

确定状态
    研究最优策略的最后一步
    化为子问题
转移方程
    根据子问题定义得到
初始条件和边界情况
计算顺序

首先,我们定义一个 dp[] 数组,其中第 i 个元素表示以下标为 i 的字符结尾的最长有效子字符串的长度。

确定状态:

最后一步:

对于最优的策略,一定有最后一个元素 s[i].
所以,我们先看第 i 个位置,这个位置的元素 s[i] 可能有如下两种情况:

  1. s[i] == ′(′ :此时,s[i] 无法和其之前的元素组成有效的括号对,所以,dp[i] = 0。

  2. s[i] == ′)′ :此时,需要看其前面的元素来判断是否形成有效括号对。
    情况1:
    s[i−1] == ′(′,即 s[i] 和 s[i−1] 组成一对有效括号,有效括号长度新增长度2,i 位置的最长有效括号长度为其前2个位置的最长括号长度加上当前位置新增的2,我们无需知道 i−2 位置的字符是否可以组成有效括号对。那么有:dp[i] = dp[i−2] + 2
    情况1情况2
    情况2:

    s[i−1] == ′)′,这种情况下,如果前面有和s[i]组成有效括号对的字符,即形如((…)),这样的话,就要求s[i−1]位置必然是有效的括号对,否则s[i]无法和前面的字符组成有效括号对。

    这时,我们只需要找到和s[i]配对的位置,并判断其是否是 ( 即可。和其配对的位置为:i−dp[i−1]−1。

    如果:s[i−dp[i−1]−1] == ′(′ :
    有效括号长度新增长度2,i 位置的最长有效括号长度为 i-1 位置的最长括号长度加上当前位置新增的2,那么有:
    dp[i] = dp[i−1] + 2
    值得注意的是,i−dp[i−1]−1 和 i 组成了有效括号对,这将是一段独立的有效括号序列,如果之前的子序列是形如 ()() 这种序列,那么当前位置的最长有效括号长度还需要加上这一段。所以:dp[i] = dp[i−1] + dp[i−dp[i−1]−2] + 2

子问题:

根据上面的分析,我们得到了如下两个计算公式:

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

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

那么,求dp[i]就变成了求dp[i−1]、 dp[i−2]、dp[i−dp[i−1]−2]的子问题。
这样状态也明确了:设dp[] 数组,其中第 i 个元素表示以下标为 i 的字符结尾的最长有效子字符串的长度。

转移方程:

子问题明确后,转移方程直接由子问题得到:

if s[i] == '(' :
    dp[i] = 0
if s[i] == ')' :
    if s[i - 1] == '(' :
        dp[i] = dp[i - 2] + 2 #要保证i - 2 >= 0

    if s[i - 1] == ')' and s[i - dp[i - 1] - 1] == '(' :
        dp[i] = dp[i - 1] + dp[i - dp[i - 1] - 2] + 2 #要保证i - dp[i - 1] - 2 >= 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值