题目
删除最小数量的无效括号,使得输入的字符串有效,返回所有可能的结果。
说明
输入可能包含了除 ( 和 ) 以外的字符。
示例1
输入: "()())()"
输出: ["()()()", "(())()"]
示例2
输入: "(a)())()"
输出: ["(a)()()", "(a())()"]
示例3
输入: ")("
输出: [""]
思路
- 用一个队列保存,每次删除一个括号时的字符串。
- 遍历字符串,一次尝试删除一个括号,用哈希表保存该字符串。如果该字符串出现在哈希表中则跳过,否则加入哈希表,并加入到队列中。
- 每次遍历完删除括号数相同的所有字符串。如果当前字符串不合法,则再遍历该字符串,再选择一个括号删,并保存到队列中。如果当前字符串合法,则把和当前字符串长度相同的字符串检查完后结束。
代码
class Solution {
public:
bool isValid( string& str ) {
int cnt = 0;
for ( int i = 0; i < str.size(); ++i ) {
if ( str[i] == '(' )
++cnt;
else if ( str[i] == ')' )
--cnt;
if ( cnt < 0 ) return false;
}
return cnt == 0;
}
vector<string> removeInvalidParentheses(string s) {
unordered_set<string> strSet;
vector<string> res;
queue<string> q; // 队列每次开始保存着相同删除次数的括号
q.push( s );
strSet.insert( s );
bool found = false;
while ( !q.empty() ) {
int size = q.size();
while ( size-- ) {
string str = q.front();
q.pop();
if ( isValid( str ) ) {
res.push_back( str );
found = true; // 找到最少删除得到的有效字符。
}
if ( found ) continue; // 把所有最少删除次数有效的保存后跳处循环
for ( int i = 0; i < str.size(); ++i ) {
if ( str[i] == '(' || str[i] == ')' ) {
string tempStr = str.substr( 0, i ) + str.substr( i + 1 );
if ( strSet.count( tempStr) == 0 ) {
q.push( tempStr );
strSet.insert( tempStr );
}
}
}
}
if ( found ) break;
}
return res;
}
};