题目描述
删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果。
说明: 输入可能包含了除 ( 和 ) 以外的字符。
示例:
输入: "()())()"
输出: ["()()()", "(())()"]
输入: "(a)())()"
输出: ["(a)()()", "(a())()"]
输入: ")("
输出: [""]
题目链接: https://leetcode-cn.com/problems/remove-invalid-parentheses/
思路
使用 bfs 来做。一层一层地遍历,如果当前层有字符串有效(括号匹配),则说明我们找到了删除最小括号的答案,就不需要遍历下一层了。代码如下:
class Solution {
public:
vector<string> removeInvalidParentheses(string s) {
if(s.empty()) return {""};
if(isValid(s)) return {s};
queue<string> q;
unordered_set<string> lookup; // 记录字符串是否被访问过
vector<string> ans;
q.push(s);
lookup.insert(s);
while(!q.empty()){
int n = q.size();
for(int i=0; i<n; i++){
string cur = q.front(); q.pop();
for(int i=0; i<cur.size(); i++){
string temp = cur;
if(temp[i]!='(' && temp[i]!=')') continue;
string ss = temp.erase(i, 1); // 注意 erase 的用法,表示删除从第 i 位置开始的 1 个字符
//cout<<ss<<endl;
if(lookup.count(ss)==0 && isValid(ss)) ans.push_back(ss);
else if(lookup.count(ss)==0) q.push(ss);
lookup.insert(ss);
}
}
if(!ans.empty()) return ans; // 这一层找到答案,无需遍历下一层
}
return ans;
}
/*判断 s 中的括号是否匹配*/
bool isValid(string s){
int cnt = 0;
for(auto c:s){
if(c=='(') cnt++;
else if(c==')') cnt--; // 使用 else if,不是 else,因为 s 中可能有除括号外的其他字符
if(cnt<0) return false;
}
return cnt==0;
}
};
删除字符串的 erase 函数需要注意,使用方法为 s.erase(pos, cnt),表示从位置 pos 开始(包含 pos)删除 cnt 个字符。