【问题标题】:Find the longest subsequence of balanced brackets in linear time在线性时间内找到最长的平衡括号子序列
【发布时间】:2021-01-06 06:40:28
【问题描述】:

我们有 3 种类型的括号:'['、'('、'{'。

检查括号的顺序是否平衡并不难,但这个问题似乎有点棘手。

让我们考虑一个例子:“()({[]”。在这种情况下,答案将是“()”或“[]”(它们的长度都是 2)

但我们也有这样的例子:“()({[]})”。在这种情况下,答案将是这个序列本身(嗯,因为它是平衡的)。但在某些时候,我们将迭代与前一个示例相同的子序列。那么,我们如何“合并”这些答案呢?

为了更好地理解我的挣扎,让我解释一下。

再说一遍,前面的例子。当我们迭代这样的子序列“()({[]”时,我们有最大长度2和两个子序列之一(“[]”或“()”)。但到最后我们应该得到这个:“() ({[]})"。

处理这个括号序列的首选方法是什么?

【问题讨论】:

    标签: algorithm


    【解决方案1】:

    想象一堆元组,每个元组代表(括号,括号索引) 并按以下方式推送堆栈:

    • 如果你看到一个左括号推动元组(括号,索引)
    • 如果您看到一个右括号并且堆栈上的前一个括号是一个匹配的左括号,则弹出该括号并获取弹出的元组的索引。并将一个元组 (index-of-opening-bracket, index-of-close-bracket) 添加到平衡括号列表中。你需要这个列表来计算最终的结果。
    • 如果您看到一个右括号并且前一个括号也是一个右括号,只需将其推入堆栈即可。
    • 如果您看到一个右括号,并且如果前一个括号(即堆栈顶部)是一个不匹配的左括号,则只需重置堆栈,因为您无法获得平衡的括号。

    在遍历整个括号序列后,您将最终进入平衡括号元组的空列表(参见第二个项目符号),或者最终进入平衡括号元组列表中的一个或多个项目。现在你必须遍历这个列表来获得平衡括号的最大长度。

    对于示例 ()({[]}),您将获得元组列表:

    (0, 1), (4, 5), (3, 6), (2, 7)。

    如您所见, (2, 7) 包含 (4, 5), (3, 6) 并且可以压缩为 (0, 1), (2, 7) 并且这两个可以合并为 (0 , 7) 这将导致长度为 8。

    我将把实现细节留给你。

    【讨论】:

    • 成功实施
    • @math-traveler 不错!
    【解决方案2】:

    从一个空栈和一个初始化为零的 max_length 开始。

    处理开括号时,将括号类型及其索引添加到堆栈中。

    在索引 i 处处理右括号时:

    1. 如果堆栈顶部是匹配的开口支架,请将其从堆栈中移除。然后找到新栈顶的索引,比如 j。现在 max_length = max(max_length, i-j)。将 nil(堆栈中没有任何内容)视为索引 -1。
    2. 否则,将右括号类型及其索引添加到堆栈中。

    例如[}[]{}(为简洁起见,我将使用括号:索引来表示堆栈)

    最初,max_len = 0,堆栈为空。

    1. 进程 [ 在索引 0 处:堆栈 = [:0
    2. 索引 1 处的进程 }:堆栈 = [:0, }:1
    3. 在索引 2 处处理 [:堆栈 = [:0, }:1, [:2]
    4. process ] 在索引 3:stack = [:0, }:1,我们更新 max_len = max(0, 3-1) = 2
    5. 进程 { 在索引 4:堆栈 = [:0, }:1, {:4
    6. process } 在索引 5:stack = [:0, }:1,我们更新 max_len = max(2, 5-1) = 4

    这在时间和空间上是线性的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-15
      • 2015-02-19
      • 2014-11-15
      • 2022-06-30
      • 2015-08-26
      • 1970-01-01
      • 1970-01-01
      • 2012-05-15
      相关资源
      最近更新 更多