作者:MJ昊
公众号:程序猿的编程之路
今天是 昊 的算法之路第16天,今天分享的是LeetCode第1249题移除无效的括号的解题思路。这是一道中等
难度的题目,考察了对栈的使用以及如何有效处理字符串中的括号匹配问题。
题目描述简要回顾
给定一个字符串 s,其中只包含小写字母和括号 “()”。你需要从字符串中删除最少数目的 (
或者 )
(可以删除任意位置的括号),使得剩下的「括号字符串」有效。
解题思路
这道题的关键在于使用栈来跟踪括号的匹配状态:
- 遍历字符串时,遇到左括号
(
,将其下标压入栈中。 - 遇到右括号
)
时:- 如果栈非空,说明可以匹配一个左括号,弹出栈顶元素。
- 如果栈为空,说明这个右括号无效,标记删除。
- 遍历完成后,如果栈中还有未匹配的左括号,同样需要标记删除它们。
- 最终通过过滤这些无效括号,返回结果。
代码实现:
var minRemoveToMakeValid = function (s) { const stack = []; const res = s.split(''); const len = res.length; for (let i = 0; i < len; i++) { if (res[i] === '(') stack.push(i); if (res[i] === ')') { if (stack.length > 0) { // 若栈中有值,说明之前有落单左括号 // 刚好匹配右括号,作一次抵消 stack.pop(); } else { // 栈中无值,说明之前没有落单的左括号了 // 当前右括号是多余的,删除 res[i] = ''; } } } // 栈中剩下的值,是所有落单的左括号 const lenStack = stack.length; for (let i = 0; i < lenStack; i++) { // 将落单的左括号删除 res[stack[i]] = ''; } return res.join(''); };
复杂度分析
-
时间复杂度:O(n)遍历字符串一次 O(n),处理栈中的剩余括号也是 O(n)。
-
空间复杂度:O(n)需要一个栈来存储左括号的索引,最坏情况下栈的大小为 n。
总结
这道题的解法采用了栈来实现括号的匹配,利用一次遍历找出所有无效的括号,并在最后移除它们。这样的方法在时间和空间上都非常高效,是解决括号匹配问题的经典思路。