题目地址
https://leetcode.com/problems/remove-invalid-parentheses/description/
题目描述
Remove the minimum number of invalid parentheses in order to make the input string valid. Return all possible results.
Note: The input string may contain letters other than the parentheses ( and ).
Example 1:
Input: "()())()"
Output: ["()()()", "(())()"]
Example 2:
Input: "(a)())()"
Output: ["(a)()()", "(a())()"]
Example 3:
Input: ")("
Output: [""]
思路
我们的思路是先写一个函数用来判断给定字符串是否是有效的。 然后再写一个函数,这个函数
依次删除第i个字符,判断是否有效,有效则添加进最终的返回数组。
这样的话实现的功能就是, 删除一个
小括号使之有效的所有可能。因此只需要递归调用依次删除第i个字符
的功能就可以了。
而且由于题目要求是要删除最少的小括号,因此我们的思路是使用广度优先遍历,而不是深度有限的遍历。
没有动图,请脑补
关键点解析
-
广度优先遍历
-
使用队列简化操作
-
使用一个visited的mapper, 来避免遍历同样的字符串
代码
/* * @lc app=leetcode id=301 lang=javascript * * [301] Remove Invalid Parentheses * * https://leetcode.com/problems/remove-invalid-parentheses/description/ * * algorithms * Hard (38.52%) * Total Accepted: 114.3K * Total Submissions: 295.4K * Testcase Example: '"()())()"' * * Remove the minimum number of invalid parentheses in order to make the input * string valid. Return all possible results. * * Note: The input string may contain letters other than the parentheses ( and * ). * * Example 1: * * * Input: "()())()" * Output: ["()()()", "(())()"] * * * Example 2: * * * Input: "(a)())()" * Output: ["(a)()()", "(a())()"] * * * Example 3: * * * Input: ")(" * Output: [""] * */ var isValid = function(s) { let openParenthes = 0; for(let i = 0; i < s.length; i++) { if (s[i] === '(') { openParenthes++; } else if (s[i] === ')') { if (openParenthes === 0) return false; openParenthes--; } } return openParenthes === 0; }; /** * @param {string} s * @return {string[]} */ var removeInvalidParentheses = function(s) { if (!s || s.length === 0) return [""]; const ret = []; const queue = [s]; const visited = {}; let current = null; let removedParentheses = 0; // 只记录最小改动 while ((current = queue.shift())) { let hit = isValid(current); if (hit) { if (!removedParentheses) { removedParentheses = s.length - current.length } if (s.length - current.length > removedParentheses) return ret.length === 0 ? [""] : ret;; ret.unshift(current); continue; } for (let i = 0; i < current.length; i++) { if (current[i] !== ')' && current[i] !== '(') continue; const subString = current.slice(0, i).concat(current.slice(i + 1)); if (visited[subString]) continue; visited[subString] = true; queue.push(subString); } } return ret.length === 0 ? [""] : ret; };
扩展
相似问题:
validParentheses
LeetCode题解计算机为什么是基于二进制的?可以是三进制么?二进制有什么好处?题解:为什么叫电子计算机?算盘应该没有二进制
LeetCode题解深度优先遍历和回溯的关系?深度优先遍历的范围更大还是回溯的范围更大?为什么?题解:我的理解是:dfs是回溯思想的一种体现- 回溯:是在整个搜索空间中搜索出可行解,在搜索过程中不断剪枝回退,这是回溯的思想,这个搜索空间并没有限制于特定的数据结构。- dfs:dfs是指特定的数据结构中如图,树(特殊的图)中搜索答案,范围限制在了特定的数据结构。个人拙见。
LeetCode题解盲人买袜子。他们都各自买了两对黑袜和两对白袜,八对袜子的布质、大小完全相同,而每对袜子都有一张商标纸连着。两位盲人不小心将八对袜子混在一起。他们每人怎样才能取回黑袜和白袜各两对呢?题解:暴力破解, 把袜子都拆开 一人一只 哈哈
LeetCode题解10个小球,随机分到12个盒子里,求恰好10个盒子都为空的概率。10个小球,随机分到12个盒子里,求恰好10个盒子都为空的概率。要求用程序模拟十万次,暴力求出该概率来自:字节跳动 算法工程师一面的第一题 (3月30日,60分钟,牛客网视频面)https://www.nowcoder.com/discuss/395924
LeetCode题解微信红包微信红包 如何分配 让每个人在数学期望上是一样的?在概率论和统计学中,数学期望(mean)(或均值,亦简称期望)是试验中每次可能结果的概率乘以其结果的总和,是最基本的数学特征之一。 它反映随机变量平均取值的大小。 需要注意的是,期望值并不一定等同于常识中的“期望”——“期望值”也许与每一个结果都不相等。 期望值是该变量输出值的平均数。