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());
}
};
本文探讨了一个利用回溯算法解决去除无效括号问题的方法,详细介绍了辅助函数findNumToRemove的作用以及backtracking的核心步骤。同时,文章强调了在实现过程中需要注意的关键点,如确保括号序列合法、避免重复结果以及正确处理不同字符类型。
1240

被折叠的 条评论
为什么被折叠?



