leetcode 301. Remove Invalid Parentheses

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 ).

Example 1:

Input: “()())()”
Output: [“()()()”, “(())()”]
Example 2:

Input: “(a)())()”
Output: [“(a)()()”, “(a())()”]
Example 3:

Input: “)(”
Output: [“”]
每个问题都应该第一时间想到最笨的办法
解法一:BFS
69ms

class Solution {
public:
    vector<string> removeInvalidParentheses(string s) {
        unordered_set<string>visited;
        vector<string>res;
        deque<string>cur;
        deque<string>next;
        cur.push_back(s);
        while(!cur.empty()){
            s = cur.front();
            cur.pop_front();
            if(isValid(s)){
                res.push_back(s);
                continue;
            }
            for(int i = 0; i < s.size(); i++){
                if(s[i] != '(' && s[i] != ')') continue;
                string tmp = s.substr(0, i) + s.substr(i + 1);
                if(visited.count(tmp) == 0){
                    next.push_back(tmp);
                    visited.insert(tmp);
                }
            }
            if(cur.empty() && res.size() == 0) swap(cur, next);
        }
        return res;
    }

    bool isValid(string& s){
        int sum = 0;
        for(auto c: s){
            if(c == '(') sum++;
            else if(c == ')') sum--;
            if(sum < 0) return false;
        }
        return sum == 0;
    }
};

解法二:
3ms
暴力法永远比不上观测规律法来的简单,我们可以观测到从出现错误的右括号开始,向回搜索,去除任意一个右括号都可以回复合法,因此先扫描去除一边右括号,然后反转字符串,再来一次即可。

class Solution {
private:
    char pa[2] = { '(' , ')' }; //检测右括号是否多余
    char pa_re[2] = { ')' , '(' }; //检测左括号是否多余
    void remove(string s, vector<string> &ans, int last_i, int last_j, const char pa[]) {
        for (int i = last_i, count = 0; i < s.size(); ++i) {
            if (s[i] == pa[0]) ++count;
            if (s[i] == pa[1]) --count;
            //直到我们找到有且仅有产生一个括号多余的情况
            if (count >= 0) continue;
            //前面的任意一个括号都可以去掉,如果有多个连续,则默认去掉第一个
            for (int j = last_j; j <= i; ++j)
                if (s[j] == pa[1] && (j == last_j || s[j - 1] != pa[1])) {
                    string newStr = s.substr(0, j) + s.substr(j + 1);
                    remove(newStr, ans, i, j, pa);
                }
            return;
        }

        //倒转字符串
        string reversed_str = s;
        std::reverse(reversed_str.begin(), reversed_str.end());

        //确认我们是否已经检测过左括号,如果已经检测过,则可以放入答案中,如果还没有检测则检测左括号
        if (pa[0] == '(') {
            //说明还没检测过
            remove(reversed_str, ans, 0, 0, pa_re);
        }
        else
            //已经检测过
            ans.push_back(reversed_str);
    }
public:
    vector<string> removeInvalidParentheses(string s) {
        vector<string> ans;
        remove(s, ans, 0, 0, pa);
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_36946274/article/details/80878799
今日推荐