青训营X豆包MarsCode 刷题:括号字符串最短长度计算 | 豆包MarsCode AI刷题

129 阅读3分钟

括号字符串最短长度计算

问题描述

小F拿到了一串只包含 '(' 和 ')' 的括号字符串。她可以进行以下两种操作:

  1. 将相邻的一对括号 '()' 合并为 '('
  2. 将相邻的一对括号 '()' 合并为 ')'

小F想知道,经过若干次操作后,能够将这个括号字符串的长度缩短到最小,最短的长度是多少?


测试样例

样例1:

输入:s = "()"
输出:1

样例2:

输入:s = ")("
输出:2

样例3:

输入:s = "((()))"
输出:1

这道题目要求通过特定的操作缩短括号字符串的长度,操作的条件是将相邻的 '()' 对合并成 '('')'。目的是通过这些操作使得字符串的长度尽可能地变小。

问题的核心分析:

  1. 操作1:将 '()' 合并为 '('
  2. 操作2:将 '()' 合并为 ')'

显然,目标是找到所有能够合并的 '()' 对,并尽量减少字符串的长度。

通过简单的问题分析,看起来是一到用到栈的题目,但是究竟将()合并为(还是),会对最终的结果产生影响。 为了避免合并错误导致后续无法合并的情况,我们仅考虑在遍历字符串时遍历到的,不考虑未遍历的,解题思路如下:

1.统计最开始无法匹配的 ')' 的数目:在第一个 '(' 出现之前的 ')',这些都无法匹配,是我们最短长度的一部分。

2.使用栈匹配并合并

从第一个 '(' 开始,遇到 '(' 时,将其压入栈并统计栈中的 '(' 数量。

如果遇到 ')'``'('

  • 如果栈中有 (,则弹出一个 (,并且根据栈中的情况决定是否合并为 ( 或 )

    • 如果栈中还有 '(',则将这对括号 '()' 合并为 ')',继续与栈中的 '(' 进行匹配。
    • 如果栈中没有 '(',则将这对括号 '()' 合并为 '('

3.计算最终的最短长度:遍历完成后,栈中剩下的括号就是无法匹配的部分。

4.最终结果就是:最开始无法匹配的+栈中剩下的

OK,到这一步其实还可以,代码怎么实现就有些问题。 一番思索之后感觉第二部分只能考虑递归:

递归代码如下:

image.png 逻辑解释:

  • 初始化栈:创建一个空栈 stack 用于存放未合并的括号。

  • 遍历字符串:遍历字符串中的每个字符。

    • 如果是 '(',将其压入栈中。

    • 如果是 ')',检查栈顶是否有 '('

      • 如果有,说明这对括号可以合并,移除栈顶的 '('
      • 如果没有,说明这个 ')' 没有匹配的 '(',将其压入栈中。
  • 返回栈的大小:最终栈中的元素数量表示剩余未合并的括号对数,这个数量即为最短长度。

其他的实现就较为简单了。

这道题比较新颖的就是递归调用了。

最后要注意最终的结果是由最开始无法匹配的以及最后无法匹配两部分之和构成。