LeetCode32-最长有效括号

1. 题目描述

  • 来源:力扣(LeetCode)
  • 链接:https://leetcode-cn.com/problems/longest-valid-parentheses
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

给你一个只包含'('')'的字符串,找出最长有效(格式正确且连续)括号子串的长度。

示例 1:

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

示例 2:

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

示例 3:

输入:s = ""
输出:0

提示:

0 <= s.length <= 3 * 104
s[i] 为 '(' 或 ')'

2. 题解

2.1 个人思路

(比较菜,非官方题解,官方题解更🐂🍺,复杂度更低)

思路: 涉及到括号匹配,第一反应就是使用 ,遍历字符串,左括号(则入栈,右括号)则判断是否能匹配并出栈一个左括号(,这样可以很简单的找出来输入字符串中有多少对能够匹配上的括号。但是,题目要求的是找出 最长有效(格式正确且连续)括号子串的长度,只找出能够匹配的括号对数是没办法保证它们之间是连续的。

  • 例如:对于字符串"(()(()",通过入栈出栈操作,我们可以得到该字符串中有2对能够匹配的括号,但是2对括号之间并不连续,因此实际的最长有效括号子串的长度为2而不是4。

那么如何在找到的匹配括号对的基础上,去计算真正的最长有效括号子串长度呢?通过判断它们是否连续即可!

  • 继续以字符串"(()(()"为例,找到的两对括号位置为[[1, 2], [4, 5]],它们之间少了个3,因此并不连续(被分成了2个块),所以不能计算整体的长度,而应该选择2个块中长度较长者作为输出。

2.2 算法流程

  1. 创建两个栈,命名为stack_leftstack_right,分别用来存储左括号信息和匹配到的完整括号信息;
  2. 遍历输入字符串,如果当前字符为左括号(,则将其下标推入stack_left;如果当前字符为右括号),则判断stack_left中是否为空,如不为空,则出栈一个左括号(的下标,并将匹配到的左右括号的下标都推入stack_right;如果stack_left为空,则丢弃改字符,继续循环;
  3. 遍历完成之后,我们得到了包含所有匹配完整的括号的下标信息stack_right,对其中的下标按照升序进行排序(时间复杂度不够低的原因);然后遍历排序后的stack_right,查找断点(即计算每一个连续块的子串长度),获取最长有效括号子串长度(从每个连续块子串长度中选择最长的作为输出)。

3. 代码实现

Python

class Solution:
    def longestValidParentheses(self, s: str) -> int:
        # 使用 栈 进行判断?
        stack_left = []
        stack_right = []
        for idx, c in enumerate(s):
            if c == '(':
                # 左括号: 入栈
                stack_left.append(idx)
                continue
            else:
                # 右括号: 判断栈中是否存在与之匹配的左括号,存在则 tmp_len + 2,并出栈一个左括号
                # 否则判断 max_len 与 tmp_len 的大小,并重置 tmp_len = 0
                if len(stack_left) != 0:
                    # stack_right.append([stack_left[-1], idx])
                    stack_right.append(stack_left[-1])
                    stack_right.append(idx)
                    stack_left.pop()
        
        # 排序
        stack_right.sort()
        if len(stack_right) == 0:
            return 0
        
        # 断点
        max_len = 0
        tmp_len = 1
        for i in range(1, len(stack_right)):
            if stack_right[i] - stack_right[i-1] == 1:
                tmp_len += 1
            else:
                max_len = max(max_len, tmp_len)
                tmp_len = 1
        max_len = max(max_len, tmp_len)
        return max_len

C++
我又没写!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值