1. 程式人生 > >301. Remove Invalid Parentheses

301. Remove Invalid Parentheses

ever 就是 size push 解法 == 答案 push_back 產生

問題描述:

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來解答這道題。

對string的每一個 ‘(‘ ‘)‘ 我們都刪除一下試試看看能不能構成一個合法的括號匹配。

對於非 ‘(‘ ‘)‘ 我們選擇跳過。

由於我們只需要找最少操作的字符串。所以我們可以記錄一個長度:

    當遇到的字符串的長度與給出字符串長度的差大於這個長度時,說明我們已經記錄完所有最少操作的長度啦。

需要註意的幾個點:

  1. 操作後的字符串可能會重復,為了避免重復,用set來存儲並且檢查

  2.檢查字符串是否合法時,跳出循環後需檢查計數器是否大於0,若大於0則說明有多余的左括號。

  3.原字符串可能就是一個有效的匹配

學習一下跑的比較快的解法。遞歸解法。

大佬的思路是找到出現重復的‘)‘對之前的字符串中為‘)‘的進行刪除,若有連續的為了保證不重復,則只刪除第一個。

再對字符串的後面部分進行檢查。

當查完後,再對是否有重復的‘(‘ 進行檢查。

雖然我覺得還是有點暈但這個運行效率確實666

還有Grandyang總結的所有解法

代碼:

BFS的解答:

class Solution {
public:
    vector<string> removeInvalidParentheses(string s) {
        vector<string
> ret; if(isValid(s)){ ret.push_back(s); return ret; } unordered_set<string> st; queue<string> q; q.push(s); int movement = INT_MAX; int sLen = s.size(); while(!q.empty()){ string cur = q.front(); q.pop(); int n = cur.size(); if(n + movement == sLen) break; for(int i = 0; i < n; i++){ string temp = cur; if(temp[i] != (&& temp[i] != )) continue; temp.erase(i, 1); if(isValid(temp)){ if(sLen - n + 1 < movement){ movement = sLen - n + 1; } if(!st.count(temp)){ ret.push_back(temp); } }else{ if(!st.count(temp)){ q.push(temp); } } st.insert(temp); } } return ret; } private: bool isValid(string s){ int cnt = 0; for(int i = 0; i < s.size(); i++){ if(s[i] == () cnt++; else if(s[i] == )){ cnt--; if(cnt < 0) return false; } } if(cnt > 0) return false; return true; } };

運行速度很快的解答:

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;
    }
};

301. Remove Invalid Parentheses