leetcode 删除无效的括号 困难_暴搜

 

 

每个位置的括号删,或者不删,即 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);  //
    }
};