力扣32 最长有效括号

23 篇文章 0 订阅
16 篇文章 0 订阅
32. 最长有效括号
给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。

示例 1:

输入: "(()"
输出: 2
解释: 最长有效括号子串为 "()"
示例 2:

输入: ")()())"
输出: 4
解释: 最长有效括号子串为 "()()"

这是道困难题,看到了括号,我第一想到的就是栈,因为对于匹配括号的题,栈这种数据结构是非常好用的。其次最长有效,这几个字在动态规划题目中经常遇见,所以不妨两者都可以考虑对应解法

动态规划

我们假设DP数组表示以当前字符作为结尾,其能匹配的括号长度
举个例子

index: 0 1 2 3 4 5
括号:  ( ( ( ( ) ) 
DP数组:0 2 0 0 2 4

我们假设当前DP[i] 是i = 4的情况,那么如何推断出DP[i+1]?
首先我们可以知道括号匹配时,其结尾一定是右括号,此时我们条件判断时当结尾为右括号才判断

其次,如果前面已经有匹配的括号,我们自然要跳过
比如index=5前面有了index=4匹配的括号,我们需要加上前面这个匹配的,即加上dp[-1],而另外一点,与index=5匹配的括号肯定不在index=4匹配括号的范围内,因此我们需要跳过,即跳过i - dp[i-1] - 1
此时如果s[i-dp[i-1]-1] 为左括号时,则匹配成功,加2
最后我们还要考虑s[i-dp[i-1]-1]前面是否有匹配,即加dp[i-dp[i-1]-2]

最后状态转移公式为:dp[i] = dp[i-1] + dp[i-dp[i-1]-2] + 2
这些情况可能会导致数组越界,因此我们还需要额外判断使得索引在数组范围内
下面是python代码

class Solution:
    def longestValidParentheses(self, s: str) -> int:
        """
        动态规划

        初始化一个全0的dp数组
        代表以改字符结尾的括号长度


        :param s:
        :return:
        """
        n = len(s)
        if n == 0:
            return 0
        dp = [0]*n
        for i in range(len(s)):
            if s[i] == ')' and i - dp[i-1] - 1>=0 and s[i-dp[i-1]-1] == '(':
                dp[i] = dp[i-1] + dp[i-dp[i-1]-2] + 2
        return max(dp)

index: 0 1 2 3 4 5 6
括号:  ( ) ) ( ( ) )

我们先往栈里放入-1

栈:-1

我们是将数组的索引入栈,当是左括号的时候,就将索引入栈,如果是右括号,则出栈,将当前索引与栈顶元素相减,得到length
并且维护一个最大长度max_length
一开始index=0是左括号,入栈

栈 :-1 0

然后index = 1是右括号,出栈,此时栈里只剩-1,而1 - (-1) = 2,记为length

栈:-1 

index = 2是右括号,相对于分割了子串,将-1出栈,此时栈里面没有元素,将 2 入栈

栈:2 

index = 3, 4都是左括号,入栈

栈:2 3 4

index = 5 是右括号,将4出栈,此时 5 - 3 = 2

 栈: 2 3 

类似推导得出最后为4
下面是代码

    def longestValidParentheses2(self, s: str) -> int:
        """
        使用栈
        :param s:
        :return:
        """
        stack = [-1]
        length = 0
        max_length = 0
        for i in range(len(s)):
            if s[i] == '(':
                stack.append(i)
            else:
                stack.pop()
                if stack == []:
                    stack.append(i)
                else:
                    length = i - stack[-1]
                    max_length = max(max_length, length)
        return max_length
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值