LeetCode——最长有效括号(自己想出来的思路)

本文介绍了一种使用栈的数据结构解决寻找字符串中最长有效括号子串的问题的方法,并提供了详细的解析过程及Python实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。

示例 1:

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

示例 2:

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

思想

看到括号匹配问题,首先想到了栈,这道题也确实要用栈.

第一种异常情况,右括号多出来:看示例我们发现右括号会多出来,这种情况是非常容易解决的,就是以右括号为边界,将右括号之间符合匹配规则的sum出来,然后取最大值。

第二种异常情况,左括号多出来:还有另一种情况,就是左括号多的时候,这里由于本人愚笨,花了很多时间,左括号之所以麻烦是因为当你遍历到‘)’时,只要没有‘(‘’则可以判断结束了,而遍历到‘(’就无法这么判断了,因为后面可能有')',举几个比较恶心的例子:

“(((())()(()(()))))))))))”

"((()((((()(((((()()()()()((((()))))(()))))"

这里因为就算知道了'('的数量,你也无法判断到哪里是异常发生点。

废话了一些,下面进入正题,首先我们要找到异常发生点,就是不是有效括号子串了,可能有无数个异常发生点,我们只要求出异常发生点之间的有效括号子串长度就可以了,然后取出最大的值。

接下来介绍异常点怎么找,如何找到异常点呢,这里很难通过"("的数量或者位置来查找,关键的一步来了,既然我们要把'('压入栈中,那我们就通过这个栈来找到了,那些多余出来的'('就是我们的异常点,那这里就有个问题,知道了异常点,怎么求异常点之间的子串长度,这里我们就要脑筋急转弯了,将子串长度压入这个栈不就可以了,栈结构就会像这样【异常点,子串长度,异常点,子串长度】。当然这里的子串长度不能一下子求出最长子串长度,但是我们可以匹配一个括号就压入一个长度。

代码

这里用的是python写的,C++或者java可以将数字转为字符串,压入栈中。

class Solution:
    def longestValidParentheses(self, s):
        """
        :type s: str
        :rtype: int
        """
        if len(s) == 0:
            return 0
        lefts = []#栈
        self.validlen = 0#当前匹配的长度
        maxlen =0 #最大子串长度
        for index, ch in enumerate(s):
            #pring(lefts) #可以看每一次遍历,栈结构的变化
            if ch == '(':
                if self.findLeftCnt(lefts):#这一步是防止有多个(,无法计算最长子串
                    lefts.append(self.validlen)#如果左边有多余的左括号,则添加当前validlen
                    self.validlen = 0 #重置当前匹配长度
                lefts.append('(') #压栈
            elif ch == ')':
                if '(' in lefts:#有左括号,则添加长度
                    self.validlen += 2
                    lefts.pop(self.findlastLeft(lefts))#弹出最近的一个(
                    if '(' not in lefts:
                        lefts.append(self.validlen)#先保存当前所得到的长度
                        self.validlen = 0
                    else:
                        if index == len(s) - 1:
                            lefts.append(self.validlen)  # 先保存当前所得到的长度
                            self.validlen = 0
                else:#没有匹配的左括号
                    lefts.append(')')
        # print(lefts)  #如果看不懂思路,请打印最后的栈结构
        #下面就是找到最大的子串
        templen = 0#保存异常点之间的子串长度
        for ch in lefts:
            if isinstance(ch, str):#发现一个异常点,则重新计算下一个异常点之间的子串长度
                if templen > maxlen:#如果不是最大的子串
                    maxlen = templen
                templen = 0
            else:
                templen += ch
        if templen > maxlen:#因为栈末尾不一定有异常点,所以要加一步
            maxlen = templen
        return maxlen

    def findlastLeft(self,lefts):
        """
        找到最靠近栈顶的'('位置
        :type lefts: 栈
        :rtype: 最靠近栈顶的'('位置
        """
        index = len(lefts)-1
        while index >=0:
            if lefts[index] == '(':
                return index
            index -= 1
        return index
    def findLeftCnt(selfs,lefts):
        """
        这里不能通过数量判断,否则会超时
        判断栈中是否有(
        :param lefts: 栈
        :return: 判断'('是否大于0
        """
        cnt = 0
        for ch in lefts:
            if ch == '(':
                return True
        return False
if __name__ =="__main__":
    res = Solution()
    #'(()()(((((((())))))))'
    print(res.longestValidParentheses(")()())()()("))
    pass

结果

我的代码不仅可以返回长度,还可以返回最长子串内容,只需要将异常点换位index就可以。.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值