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())()"] ")(" -> [""]
去掉最少的括号数使得总的括号有效,返回所有可能的结果
思路:使用广度优先遍历或者深度优先遍历
括号类的题目,首先维护一个变量,遇到左括号就自增,遇到右括号就自减。当这个变量小于0时,说明右括号的数量多余了。这个时候应该移去一个有括号,使得
括号有效。移出当前位置前面的任何一个右括号都是可以的。
这个题目要求得到所有的可能的结果。因此应该把能移出的右括号都试一遍。但是当两个右括号相邻时出现重复的结果。我们约定只移出最右边的括号。
将改动后的字符串递归调用,递归调用的遍历位置从前面扫描到的位置开始,去除括号的遍历位置,从前一次去除括号的位置开始。这样能保证不缺不漏
当i的位置走到字符串最后时,大循环结束。
翻转字符串。
后面的处理体现递归的技巧
class Solution { public: vector<string> removeInvalidParentheses(string s) { vector<string> res; char a[2]={'(',')'}; remove(s,res,0,0,a); return res; } void remove(string s,vector<string>& res,int right_i,int left_j,char* a){ for(int count=0;right_i<s.size();right_i++) { if(s[right_i]==a[0]) count++; else if(s[right_i]==a[1]) count--; if(count>=0) continue; //右括号多了 for(int j=left_j;j<=right_i;j++) { if(s[j]==a[1]&&(j==left_j||s[j-1]!=a[1]))//如果第一个就是右括号,或者是连续右括号的第一个 remove(s.substr(0,j)+s.substr(j+1,s.size()-j-1),res,right_i,j,a); } return ;//注意这个外循环不是一直循环到底,而是遇到需要删除的地方就递归下去,因为下面的递归会解决后面的遍历,这里不能继续遍历下去 } string reversed=s; reverse(reversed.begin(),reversed.end()); if(a[0]=='(') { swap(a[0],a[1]); remove(reversed,res,0,0, a);//反转也要处理一遍,结果才是正确的 } else res.push_back(reversed); } };