题目:
给你一个由若干括号和字母组成的字符串 s ,删除最小数量的无效括号,使得输入的字符串有效。 返回所有可能的结果。答案可以按 任意顺序 返回。 示例 1: 输入:s = "()())()" 输出:["(())()","()()()"]
示例 2: 输入:s = "(a)())()" 输出:["(a())()","(a)()()"]
示例 3: 输入:s = ")(" 输出:[""]
解题思路:
首先需要判断字符串是否有效:
- 就是遇到左括号,计数 +1
- 遇到字母不算,遇到右括号,计数 -1
- 计数为负,说明右括号在前了,直接返回无效
- 否则循环完整个字符串,计数为 0 则有效
const valid = function (str) {
let count = 0;
for (let c of str) {
if (c === '(') {
count++;
} else if (c === ')') {
count--;
}
if (count < 0) {
return false;
}
}
return count === 0;
}
然后尝试删除字符串中每一个括号字符,并检查是否有效:
- 如果当前字符和前一位字符相同,则不必尝试,因为效果是一样的
- 只删除当前字符,并重新组合成新的字符串
- 因为有字母,字母不用删,只删除左右括号,将所有的可能都放入一个 Set 里,因为 Set 自动去重。
let str = s;
let set = new Set();
for (let i = 0; i < str.length; i++) {
if (i > 0 && str[i] == str[i - 1]) {
continue;
}
if (str[i] === '(' || str[i] === ')') {
let temp = str.substring(0, i) + str.substring(i + 1);
set.add(temp);
}
}
- 有可能需要删除多个字符才能合理,所以上一次循环的字符串作为下一次删除字符的模版
let curSet = new Set();
curSet.add(s);
for (let str of curSet) {
let nextSet = new Set();
for (let i = 0; i < str.length; i++) {
if (i > 0 && str[i] == str[i - 1]) { continue; }
if (str[i] === '(' || str[i] === ')') {
let temp = str.substring(0, i) + str.substring(i + 1);
nextSet.add(temp);
}
}
curSet = nextSet;
}
- 最后,要求返回的是删除最小数量字符,所以一旦有合理的字符串产生,就可以结束了
let curSet = new Set();
curSet.add(s);
let ans = [];
while (true) {
for (let t of curSet) {
if (valid(t)) {
ans.push(t);
}
}
if (ans.length > 0) { return ans; }
let nextSet = new Set();
for (let str of curSet) {
for (let i = 0; i < str.length; i++) {
if (i > 0 && str[i] == str[i - 1]) {
continue;
}
if (str[i] === '(' || str[i] === ')') {
let temp = str.substring(0, i) + str.substring(i + 1);
nextSet.add(temp);
}
}
}
curSet = nextSet;
}
完整代码:
/**
* @param {string} s
* @return {string[]}
*/
var removeInvalidParentheses = function(s) {
const valid = function (str) {
let count = 0;
for (let c of str) {
if (c === '(') {
count++;
} else if (c === ')') {
count--;
}
if (count < 0) {
return false;
}
}
return count === 0;
}
let curSet = new Set();
curSet.add(s);
let ans = [];
while (true) {
for (let t of curSet) {
if (valid(t)) {
ans.push(t);
}
}
if (ans.length > 0) { return ans; }
let nextSet = new Set();
for (let str of curSet) {
for (let i = 0; i < str.length; i++) {
if (i > 0 && str[i] == str[i - 1]) {
continue;
}
if (str[i] === '(' || str[i] === ')') {
let temp = str.substring(0, i) + str.substring(i + 1);
nextSet.add(temp);
}
}
}
curSet = nextSet;
}
};