每个位置的括号删,或者不删,即 2^n 复杂度暴搜,然后剪枝优化。
可以预处理出是括号合法需要删除多少个括号。(可进一步细分为左括号多少个,右括号多少个进行优化)。
+ 如果已删除个数已经大于预先要求的个数,直接 return.
+ 记录当前序列已经拥有的左括号与右括号,如果出现 右括号数量大于左括号数量的情况,直接 return. 因为括号已经不合法。
class Solution { public: vector<string> removeInvalidParentheses(const string &s) { int lef = 0, rig = 0; int delNums = 0; for(int i = 0; i < s.size(); ++ i) { if(s[i] == '(') ++ lef; else if(s[i] == ')') ++ rig; if(rig > lef) { delNums += rig - lef; lef = rig = 0; } } delNums += lef - rig; string retStr; solve(s, delNums, 0, retStr, 0, 0, 0); return vector<string>(ret.begin(), ret.end()); } private: unordered_set<string> ret; void solve(const string &s, const int &delNums, int i, string &retStr, int lef, int rig, int del) { if(rig > lef) return; // 剪枝, 如果 右括号数量已经大于左括号数量, 括号序列不合法 if(del > delNums) return ; if(i == s.size()) { if(lef == rig) ret.insert(retStr); return ; } retStr.push_back(s[i]); solve(s, delNums, i + 1, retStr, lef + (s[i] == '('), rig + (s[i] == ')'), del); // 未删 retStr.pop_back(); if(s[i] != '(' && s[i] != ')') return; // 如何不是括号, 则不用删 solve(s, delNums, i + 1, retStr, lef, rig, del + 1); // 删 } };