携手创作,共同成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情
删除无效的括号
给你一个由若干括号和字母组成的字符串
s
,删除最小数量的无效括号,使得输入的字符串有效。 返回所有可能的结果。答案可以按 任意顺序 返回。
分析
- 对于有效括号指的是一串括号,左括号在前,右括号在后,左括号和右括号的个数相等,此时就是有效括号
- 删除最小数量的无效括号,那就是得到最长有效括号子串,这样就是问题的答案,那要如何得到最长的有效括号的子串呢?
- 当遇到左括号的时候,此时有两种选择,选到子串中或者不选到子串
- 在遇到右括号的时候,如果有没有匹配到右括号的左括号就选,不然不选
- 因为是在不断的尝试,如果当前步骤不对就回退到上一个步骤,思路和解决方案比较偏向于DFS
- 这道题目在DFS搜索的时候,需要记录当前左括号的个数,便于遇到右括号的时候是选还是不选,也需要记录遍历过程中的子串,可以在回退的时候拿到当时的子串,以及需要在减少相同答案的处理
- 需要注意的是,因为题目要求的是最长的有效括号子串,因此,在DFS搜索的时候,偏向于不删除括号,所以在DFS搜索的时候遇到左括号,先做保留在做删除
代码
var removeInvalidParentheses = function(s) {
var res = [], max = 0;
dfs(s, "", 0, 0);
return res.length !== 0 ? res : [""];
function dfs(str, subRes, countLeft, maxLeft){
if(str === ""){
if(countLeft === 0 && subRes !== ""){
if(maxLeft > max)
max = maxLeft;
if(max === maxLeft && res.indexOf(subRes) === -1)
res.push(subRes);
}
return;
}
if(str[0] === '('){
dfs(str.substring(1), subRes + '(', countLeft + 1, maxLeft + 1);
dfs(str.substring(1), subRes, countLeft, maxLeft);
}else if(str[0] === ')'){
if(countLeft > 0)
dfs(str.substring(1), subRes + ')', countLeft - 1, maxLeft);
dfs(str.substring(1), subRes, countLeft, maxLeft);
}else{
dfs(str.substring(1), subRes + str[0], countLeft, maxLeft);
}
}
};
总结
- DFS在解决这种不断试探的问题的时候通常都很有效果,这道题是很好的体现
- 删除无效的括号输出有效括号的字符串,没有求删除括号的个数,所以就对这个问题进行了转换,从删除最少的转为获取最长的
- 今天也是有收获的一天