回溯算法:删除无效的括号

301. 删除无效的括号

 

关于括号相关的其他问题可见 回溯算法:括号生成秒杀所有括号类问题。本篇文章主要结合题目 删除无效的括号 总结「判断括号字符串是否有效」的条件,同时扩展出几种剪枝的策略

首先我们回顾一下如何判断一个由括号组成的字符串是否有效??

第一种方法:维护一个只存放左括号的栈,详情可见 秒杀所有括号类问题 中第一个题目的解题思路

第二种方法:对于一个字符串s来说,s的任意一个子串[0...i]中,(的数量肯定大于或等于)的数量,详情可见 回溯算法:括号生成 中的优化思路

我发现在实际题目中,第二种判定方法用到的更多!!

暴力回溯

下面我们看一种暴力的回溯代码,没有任何剪枝的版本!!

剪枝思路

当删除的字符数量已经大于最少删除数量时,剪枝!!!

我们可以提前对数据进行一些预处理,得到「最大删除的右括号数量」「最大括号对数量」

为什么可以得到这两个量呢?这就要回到上面介绍的第二种判定方法!!

对于「最大删除的右括号数量」,在我们遍历所有括号时,如果某一个子串中右括号大于左括号,那我们必然需要删掉一个右括号,所以可以得到最大需要删除的右括号数量

对于「最大括号对数量」,当我们得到所有的左右括号数量后,最大括号对的数量即为Math.min(l, r)

完整代码

下面附一张优化过程的执行时间图,如下:

8