📜  最长正确的括号子序列的范围查询(1)

📅  最后修改于: 2023-12-03 14:55:23.202000             🧑  作者: Mango

最长正确的括号子序列的范围查询

什么是括号序列?

括号序列是由左右括号组成的序列,左右括号必须匹配,且左右括号的数量相等。

例如,"()"、"()()"和"(())"都是括号序列,但是"("、")("和"))(("不是。

什么是最长正确的括号子序列?

最长正确的括号子序列指的是在一个给定的括号序列中,最长的连续的括号子序列,使得其中左右括号都匹配。

例如,对于括号序列"((()())())",最长的连续的括号子序列是"()()",长度为4。

如何查询最长正确的括号子序列的范围?

下面给出一个使用栈的算法,时间复杂度为O(n)。

算法思路
  1. 初始化一个空栈。
  2. 初始化start变量为-1,表示没有找到最长的括号匹配子序列。
  3. 遍历括号序列中的每个字符: a. 如果当前字符是左括号,将其下标压入栈中。 b. 如果当前字符是右括号: i. 如果当前栈为空,将start置为当前下标。 ii. 如果当前栈不为空,弹出栈顶元素表示匹配了当前右括号,计算与当前下标的差值,更新最长括号子序列长度。 (1) 如果栈为空,则长度为当前下标-start。 (2) 如果栈不为空,则长度为当前下标-当前栈顶元素。 (3) 更新start变量为栈顶元素,保留最长括号匹配子序列的左端点信息。
  4. 返回最长括号子序列的左右端点信息。
代码实现
def longest_valid_parentheses(s: str) -> tuple:
    stack = []
    start = -1
    max_len = 0
    for i, char in enumerate(s):
        if char == '(':
            stack.append(i)
        else:
            if not stack:
                start = i
            else:
                stack.pop()
                if not stack:
                    max_len = max(max_len, i - start)
                else:
                    max_len = max(max_len, i - stack[-1])
                    start = stack[-1]
    return start, start+max_len
测试样例

s = "(()",最长括号匹配子序列为"()",左右端点为(1, 2) s = ")()())",最长括号匹配子序列为"()()",左右端点为(1, 4)

总结

以上算法使用了栈来维护括号序列中左右括号的匹配关系,通过遍历括号序列来更新最长的括号匹配子序列长度。该算法简单易懂,时间复杂度为O(n),适用于较大的括号序列查询。