Problem
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())()"] ")(" -> [""]
Solution
一开始看到这道题卡住了
最主要是没想到这个辅助函数 findNumToRemove , 来算出要删除左括号和右括号的个数 ( rmLeft 和 rmRight).
得到这两个变量就好办了,就是典型的backtracking :遇到左括号,要么删除(rmLeft - 1), 要么就加到一个可能的结果里; 右括号同理;其它字符就照收
还需要注意几点:
1. 需要一个变量 open来确保是合法的一系列括号。
2. 需要用unordered_set 来存结果,因为有可能重复。
class Solution {
void findNumToRemove(const string& str, int& rmLeft, int& rmRight){
for( char c : str){
if( c == '(' ){
rmLeft++;
}
else if( c == ')' ){
if(rmLeft > 0) {
rmLeft--;
}
else {
rmRight++;
}
}
}
}
void helper( const string& str, int rmLeft, int rmRight, int idx, int open,string oneRst, set<string>& rst){
if(idx == str.size() && rmLeft == 0 && rmRight == 0 && open == 0){
rst.insert(oneRst);
return;
}
if(rmLeft < 0 || rmRight < 0 || idx == str.size() || open < 0 ) return;
char c = str[idx];
if( c == '(' ) {
helper(str, rmLeft, rmRight, idx + 1, open + 1, oneRst + c, rst); // take it
helper(str, rmLeft - 1, rmRight, idx + 1, open, oneRst, rst); // remove it
}
else if( c == ')' ) {
helper(str, rmLeft, rmRight, idx + 1, open - 1, oneRst + c, rst); //take it
helper(str, rmLeft, rmRight - 1, idx + 1, open , oneRst, rst); //remove it
}
else {
helper(str, rmLeft, rmRight, idx + 1, open, oneRst + c, rst);
}
}
public:
vector<string> removeInvalidParentheses(string s) {
int rmLeft = 0, rmRight = 0;
findNumToRemove(s, rmLeft, rmRight);
set<string> rst;
helper(s, rmLeft, rmRight, 0, 0, string(), rst);
return vector<string> (rst.begin(), rst.end());
}
};