題目相關
題目鏈接
LeetCode中國,https://leetcode-cn.com/problems/generate-parentheses/。
LeetCode中國,https://leetcode-cn.com/problems/bracket-lcci/。
兩題是一樣的。
題目描述
括號。設計一種算法,打印n對括號的所有合法的(例如,開閉一一對應)組合。說明:解集不能包含重複的子集。
示例
例如,給出 n = 3,生成結果爲:
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
題目分析
LeetCode 給出本題難度中等。
題意分析
根據給定的長度 n,構造所有可能的跨號組合。
樣例數據分析
略。
算法設計
這題一看就知道是一個搜索回溯問題。可以參考我以前寫的回溯題解。
既然已經確定是一個回溯題目,哪麼我們直接可以套用回溯模板。
搜索函數設計
設計搜索函數的核心就是確定要幾個參數。碰到這個問題,我們先不管三七二十一,將函數寫上去,然後再逐步確定需要幾個參數。
1、一個字符串,用來表述當前生成的數據是怎麼樣的。
2、一個數字,表示現在已經有幾個左括號。
3、一個數字,表示現在已經有幾個右括號。
4、一個數字,表示目標搜索字符串長度。
5、一個參數,表示已經有幾個解了。
由於 C++ 不建議函數參數超過 4 個,所以我們可以將第五個參數優化,使用類的變量來實現。或者還可以進一步優化,將目標字符串長度也優化了。這裏我們就不優化第四個參數了。這樣,我們就可以設計出一個帶有 4 個參數的搜索函數,原型如下。
/*
第一個參數:當前的字符串
第二個參數:左括號數量
第三個參數:右括號數量
第四個參數:目標長度
*/
void dfs(string path, int lpos, int rpos, int n);
搜索返回條件
自然是 lpos+rpos 和 n 進行比較。
回溯
本題的難度所在。
以前回溯的模板基本如下。
path.push_back("(");
dfs(xxxx);
path.pop_back();
本題的回溯和以前不大一樣,由於是左右括號,所以不能這樣回溯。只能通過判斷左括號和右括號來解決。具體看代碼。
AC 參考代碼
class Solution {
public:
vector<string> ans;//答案
vector<string> generateParenthesis(int n) {
string path;//當前生成的字符串
dfs(path, 0, 0, n);
return ans;
}
/*
第一個參數:當前的字符串
第二個參數:左括號數量
第三個參數:右括號數量
第四個參數:目標長度
*/
void dfs(string path, int lpos, int rpos, int n) {
if (lpos>=n && rpos>=n) {
cout << path << endl;
ans.push_back(path);
return;
}
if (lpos<n) {
//左邊括號還有,繼續加
dfs(path+"(", lpos+1, rpos, n);
}
if (rpos<n && lpos>rpos) {
dfs(path+")", lpos, rpos+1, n);
}
}
};
只能說通過了題目,算法設計一般吧。先將就一下。