301. 刪除無效的括號--Leecode刷題

刷了一個困難題,一如既往做不出來,然後看題解,然後再自己打一遍…記錄這個題的原因是,這其實是一類題目!!!先看看題目再分析。

題目描述:

刪除最小數量的無效括號,使得輸入的字符串有效,返回所有可能的結果。

說明: 輸入可能包含了除 ( 和 ) 以外的字符。

示例 1:

輸入: “()())()”
輸出: ["()()()", “(())()”]

示例 2:

輸入: “(a)())()”
輸出: ["(a)()()", “(a())()”]

示例 3:

輸入: “)(”
輸出: [""]

分析題目:

這真的是一類題,題目具有的特徵:
1.求的是一個子集
2.且子集滿足一定的條件

這類題目可以用一個方法,就是DFS

關於這題DFS的分析:

1.DFS遍歷的行爲?刪括號
2.什麼情況下刪?就是當左括號或者右括號有多的時候,正好當前遍歷的又是個多的括號,就刪!!!之後再繼續進行DFS遍歷刪除
3.出口是什麼?當沒有多餘的括號的時候!!!但注意此時還需要檢查一下當前的字符串是否合法(即左右括號是否匹配!)

解題步驟:

1. 先統計多餘的括號,注意並不是循環一遍統計左右括號個數,然後多的一方就是多餘的。
如 left= 2,right = 3,就認爲右括號多一個,因爲可能之前的不匹配!!!
正確的統計方法是,當遇到左括號left++,遇到右括號時,若left > 0 就left --,說明一對括號匹配消除,若left == 0 ,right++,那麼這樣留下來的就是多餘的括號,沒有被匹配的括號!!!

2. 然後開始DFS,從第一個字符串開始,若當前符號是多餘需要刪除,則刪除,
如:此時DFS遍歷時left = 0,right = 1,當前是s[ i ] 爲左括號則跳過,若爲右括號則刪除,
然後對後面進行遞歸DFS。
3. 直到left 爲 0 ,right爲 0,進行檢查,匹配加入set< string >

代碼如下:

class Solution {
public:
    bool checks(string s){
        int left = 0;
        for(int i = 0;i < s.size();i++){
            if(s[i] == '(') left++;
            else if(s[i] == ')'){
                if(!left) return false;
                else left--;
            }
        }

        return true;
    }

    void dfs(set<string> &result,string s,int left,int right,int index){
        if(!left&&!right){
            if(checks(s)) result.insert(s);
            return ;
        }

        for(int i = index;i < s.size();i++){
            if(s[i] == '('&&left) dfs(result,s.substr(0,i)+s.substr(i+1,s.size()-i-1),left-1,right,i);
            else if(s[i] == ')'&&right) dfs(result,s.substr(0,i)+s.substr(i+1,s.size()-i-1),left,right-1,i);
        }

    }

    vector<string> removeInvalidParentheses(string s) {

       int left = 0;
       int right = 0;

       for(int i = 0;i < s.size();i++){
           if(s[i] == '(') left++;
           else if(s[i] == ')'){
               if(left > 0) left--;
               else right++;
           }
       }

        set<string> result;
        dfs(result,s,left,right,0);

        return vector<string>(result.begin(),result.end());

    }
};

總結:
關於DFS不要怕,步驟就是,首先遞歸的操作,其次遞歸的出口!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章