LeetCode題解——22. 括號生成

題目相關

題目鏈接

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

只能說通過了題目,算法設計一般吧。先將就一下。

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