题意

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 ).

Examples:

"()())()" -> ["()()()", "(())()"]

"(a)())()" -> ["(a)()()", "(a())()"]

")(" -> [""]

Credits:

Special thanks to @hpplayer for adding this problem and creating all test cases.

Subscribe to see which companies asked this question

思路

无论是BFS还是DFS,其都是去判断字符串去掉括号的情况,如果不满足情况,则继续去除括号

题解

DFS

/**
* DFS+剪枝
*
* @param pair 多出来的遇见括号的个数
* @param index 记录字符串s的当前位置
* @param remove_left 左括号需要删除的个数
* @param remove_right 右括号需要删除的个数
* @param s 原始字符串
* @param solution 生成字符串
* @param result 存储所有的字符串结果
*/
void helper(int pair, int index, int remove_left, int remove_right, const string& s, string solution, unordered_set<string> &result) {
if (index == s.size()) {
if (pair == 0 && remove_left == 0 && remove_right == 0)
result.insert(solution);
return ;
} if (s[index] == '(') {
// 删除左边括号
if (remove_left > 0) helper(pair, index + 1, remove_left - 1, remove_right, s, solution, result);
// 回溯
helper(pair + 1, index + 1, remove_left, remove_right, s, solution + s[index], result);
}
else if (s[index] == ')') {
// 删除右边括号
if (remove_right > 0) helper(pair, index + 1, remove_left, remove_right - 1, s, solution, result);
// 回溯
if (pair > 0) helper(pair - 1, index + 1, remove_left, remove_right, s, solution + s[index], result);
}
else {
helper(pair, index + 1, remove_left, remove_right, s, solution + s[index], result);
}
}
vector<string> removeInvalidParentheses(string s) {
int remove_left = 0, remove_right = 0;
unordered_set<string> result; // 处理重复 // 计算左右两边需要删除括号的个数
for (int i = 0; i < s.size(); ++i) {
if (s[i] == '(')
remove_left++;
else if (s[i] == ')') {
if (remove_left > 0) remove_left--;
else remove_right++;
}
} helper(0, 0, remove_left, remove_right, s, "", result); return vector<string>(result.begin(), result.end());
}

BFS

  • 解法1
bool check(string s) {
int count = 0;
for (int i = 0; i < s.size(); i++) {
char tmp = s[i];
if (tmp == '(') count++;
if (tmp == ')') {
if (count == 0) return false;
count--;
}
}
return count == 0;
} /**
* 这个解法看似和上面解法类似,以为是DFS,但是其实是个BFS,思路和2是类似的,只不过用递归实现
* 删除子串的每个字符,然后进行递归
*
*
* @param begin 记录原字符串的下标,为什么是BFS的原因
* @param remove_left 需要删除左边括号的个数
* @param remove_right 需要删除右边括号的个数
* @param s 子串
* @param result 结果
*/
void helper2(int begin, int remove_left, int remove_right, string s, vector<string> &result) {
// 如果左右已经没有要删除的括号,并且符合条件,则进行收敛
if (remove_left == 0 && remove_right == 0) {
if (check(s)) {
result.push_back(s);
return;
}
} // begin是个重点,意味着从begin开始往后删,前面的字符串不再动
for (int i = begin; i < s.size(); ++i) {
string temp = s;
if (remove_left > 0 && remove_right == 0 && s[i] == '(') {
// 删除子串的每个字符,同时避免重复
if (begin == i || s[i] != s[i-1]) {
temp.erase(i, 1);
helper2(i, remove_left-1, remove_right, temp, result);
}
}
if (remove_right > 0 && s[i] == ')') {
if (begin == i || s[i] != s[i-1]) {
temp.erase(i, 1);
helper2(i, remove_left, remove_right-1, temp, result);
}
}
} }
vector<string> removeInvalidParentheses3(string s) {
int remove_left = 0, remove_right = 0;
vector<string> result; // 处理重复 // 计算左右两边需要删除括号的个数
for (int i = 0; i < s.size(); ++i) {
if (s[i] == '(')
remove_left++;
else if (s[i] == ')') {
if (remove_left > 0) remove_left--;
else remove_right++;
}
} helper2(0, remove_left, remove_right, s, result); return result;
}
  • 解法2
/**
* 通过从输入字符串中移除每一个括号,生成新的字符串加入到队列中
* 如果从队列中取出的字符串是有效的,则加入到结果列表中
* 一旦发现有效的字符串,则不再向队列中补充新的字符串,其去掉的括号数一定是最小的
* 而此时,队列中存在的元素与队列头元素去掉的括号数的差值 <= 1
* 并且,只有与队列头元素去掉括号数目相同的元素才有可能是候选答案
*
* @param s <#s description#>
*
* @return <#return value description#>
*/
vector<string> removeInvalidParentheses2(string s) {
vector<string> result;
if (s == "") {
result.push_back(s);
return result;
} unordered_set<string> visited; // 控制是否访问过字符串,因为要求不可重复
deque<string> queue;
queue.push_back(s);
visited.insert(s); bool found = false;
while (!queue.empty()) {
string temp = queue.front();
queue.pop_front(); // 每次遍历代表着需要加进来去掉一个括号的子串,层数代表删除括号的次数
// 只要第一次符合情况了,说明该字符串已经是可去掉括号数目最小的字符串层
// 意味着该层不再需要加进来任何的子串了,
if (check(temp)) {
result.push_back(temp);
found = true;
} if (found) continue;
for (int i = 0; i < temp.size(); ++i) {
if (temp[i] != '(' && temp[i] != ')') continue;
// 删除括号,生成新的字符串
string str = temp.substr(0, i) + temp.substr(i+1); if (visited.find(str) == visited.end()) {
queue.push_back(str);
visited.insert(str);
}
}
} return result;
}

Remove-Invalid-Parentheses-题解的更多相关文章

  1. Leetcode之深度优先搜索(DFS)专题-301. 删除无效的括号(Remove Invalid Parentheses)

    Leetcode之深度优先搜索(DFS)专题-301. 删除无效的括号(Remove Invalid Parentheses) 删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果. 说明 ...

  2. 301. Remove Invalid Parentheses

    题目: Remove the minimum number of invalid parentheses in order to make the input string valid. Return ...

  3. LeetCode 301. Remove Invalid Parentheses

    原题链接在这里:https://leetcode.com/problems/remove-invalid-parentheses/ 题目: Remove the minimum number of i ...

  4. [LeetCode] Remove Invalid Parentheses 移除非法括号

    Remove the minimum number of invalid parentheses in order to make the input string valid. Return all ...

  5. Remove Invalid Parentheses

    Remove the minimum number of invalid parentheses in order to make the input string valid. Return all ...

  6. Remove Invalid Parentheses 解答

    Question Remove the minimum number of invalid parentheses in order to make the input string valid. R ...

  7. [Swift]LeetCode301. 删除无效的括号 | Remove Invalid Parentheses

    Remove the minimum number of invalid parentheses in order to make the input string valid. Return all ...

  8. [leetcode]301. Remove Invalid Parentheses 去除无效括号

    Remove the minimum number of invalid parentheses in order to make the input string valid. Return all ...

  9. LeetCode301. Remove Invalid Parentheses

    Remove the minimum number of invalid parentheses in order to make the input string valid. Return all ...

  10. 301. Remove Invalid Parentheses去除不符合匹配规则的括号

    [抄题]: Remove the minimum number of invalid parentheses in order to make the input string valid. Retu ...

随机推荐

  1. JavaScript入门--慕课网学习笔记

     JAVASCRIPT—(慕课网)入门篇 我们来看看如何写入JS代码?你只需一步操作,使用<script>标签在HTML网页中插入JavaScript代码.注意, <script&g ...

  2. pytorch--cnn的理解

    class Model(nn.Module): def __init__(self): super(Model, self).__init__() self.conv1 = nn.Conv2d(1, ...

  3. 音频增益响度分析 ReplayGain 附完整C代码示例【转】

    转自:http://www.cnblogs.com/cpuimage/p/8846951.html 人们所熟知的图像方面的3A算法有: AF自动对焦(Automatic Focus)自动对焦即调节摄像 ...

  4. .net 运行中出现的错误解决方法记录

    1.应用程序无法启动,因为应用程序的并行配置不正确.有关详细信息,请参阅应用程序事件日志,或使用命令行sxstrace.exe工具. https://jingyan.baidu.com/article ...

  5. Java集合之Collection与之子类回顾

    Java学习这么久,打算这几天回顾下java的基本知识点,首先是集合. 一.常用集合类关系图 Collection |___List 有序,可重复 |___ArrayList  底层数据结构是数组,增 ...

  6. linux limits研究

    ---------------------------------------------------------------------------------------------------- ...

  7. 解决eclipse Debug时提示source not found的问题

    解决办法: 选择Change Attached  Source,添加自己的project,clean项目,重启eclipse即可.

  8. invalid byte sequence for encoding "UTF8": 0xe99d2c

    服务器还原数据库数据出错,老规矩... 字符集编码的问题 http://blog.csdn.net/beiigang/article/details/39582583 over....

  9. java 添加一组元素

    在java包中的Arrays和Collection类中都有很多实用方法,可以在一个Collection中添加一组元素,Array.asList()方法接受一个数组或是一个用逗号分隔的元素列表(使用可变 ...

  10. Mac OS 下安装mysqlclient报“mysql_config not found”的解决

    如问题所示,应该是你没有将mysql_config所在文件夹加入系统的PATH路径,解决方案下: 1.第一步找到你的mysql_config所在位置 1.1. 如果是直接安装mysql,所在位置应该是 ...