301. Remove Invalid Parentheses
阿新 • • 發佈:2018-06-17
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