「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」
前言
前面两题我们一直在找有效的括号字符串,今天虽然换了汤,但是不换药,虽然是移除无效的括号,依然需要有效括号的配对依据哟,而且,今天我们操作的对象会略有不同,不是直接操作括号了哟!
题目描述
1249. 移除无效的括号
给你一个由 '('、')' 和小写字母组成的字符串 s。
你需要从字符串中删除最少数目的 '(' 或者 ')' (可以删除任意位置的括号),使得剩下的「括号字符串」有效。
请返回任意一个合法字符串。
有效「括号字符串」应当符合以下 任意一条 要求:
空字符串或只包含小写字母的字符串 可以被写作 AB(A 连接 B)的字符串,其中 A 和 B 都是有效「括号字符串」 可以被写作 (A) 的字符串,其中 A 是一个有效的「括号字符串」
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/mi… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
题给字符串:
由'('、')'和小写字母组成的字符串例如lee(t(c)o)de)"、"a)b(c)d"、"))(("
期待字符串: 上述三个变成如下"lee(t(c)o)de"、“ab(c)d”、“”
提供转换规则:
删除题给字符串中最少的括号,使其中括号字符串为有效字符串,最终结果可以是有效括号字符串和字母的拼接,也可以是空字符串或纯字母
我们的思路:
- 首先字符串我们肯定是需要遍历的,但是我们
不用关系字母部分,只需要看括号部分,因为直接影响结果的就是我们需要删除几个括号; - 如何移除无效的括号呢?我们
让有效括号对配对,不就剩下无效的括号了吗? - 要执行字符串中字符的删除,我们可以让字符串转化为数组,通过数组下标将对应的字符删除即可,最后再归于字符串。
- 既然我们
最终要通过下标来删除,那我们只要找到要删除的无效括号的下标就行了吧! - 下面就需要进行的是有效括号的配对过程了:
1)那么我们需要左括号删除栈和右括号删除栈来存放我们要删除的左括号和右括号的下标
2)如果遍历遇到左括号,直接放到左括号删除栈里; 如果是右括号,先判断左括号删除栈里有没有元素,如果没有,说明没有左括号能与当前的右括号配对,就将该右括号的下标入到右括号删除栈里,如果有与当前右括号配对的,说明左括号删除栈的栈顶元素可以配对成功,不需要删除,直接出栈即可;
3)那么最后剩下两个删除栈中就是要删除的无效括号,合并-》遍历-》删除即可
开始解题
var minRemoveToMakeValid = function(s) {
let res = s.split(''); // 字符串可以直接遍历,但不能像数组一样用下标操作,所以需要转化为数组;
let leftDel = [], rightDel = [];
for(let i = 0; i < s.length; i++) {
if(s[i] === '(') { // 左括号直接入左删除栈
leftDel.push(i);
}
if(s[i] === ')'){
if(!leftDel.length) rightDel.push(i); // 没有与右括号配对的左括号时,右括号该删,入右删除栈
leftDel.pop(); // 有与之配对,说明左括号删除栈栈顶元素不该删除,出栈
}
}
let del = leftDel.concat(rightDel); // 合并待删除括号下表数组
for(let j = 0; j < del.length; j++) { // 遍历删除无效括号
res[del[j]] = '';
}
return res.join('');
};