題目描述:java
給出 n 表明生成括號的對數,請你寫出一個函數,使其可以生成全部可能的而且有效的括號組合。算法
例如,給出 n = 3,生成結果爲:函數
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]spa
題目解析:動態規劃code
首先,面向小白:什麼是動態規劃?在此題中,動態規劃的思想相似於數學概括法,當知道全部 i<n 的狀況時,咱們能夠經過某種算法算出 i=n 的狀況。
本題最核心的思想是,考慮 i=n 時相比 n-1 組括號增長的那一組括號的位置。blog
思路:
當咱們清楚全部 i<n 時括號的可能生成排列後,對與 i=n 的狀況,咱們考慮整個括號排列中最左邊的括號。
它必定是一個左括號,那麼它能夠和它對應的右括號組成一組完整的括號 "( )",咱們認爲這一組是相比 n-1 增長進來的括號。get
那麼,剩下 n-1 組括號有可能在哪呢?數學
【這裏是重點,請着重理解】class
剩下的括號要麼在這一組新增的括號內部,要麼在這一組新增括號的外部(右側)。List
既然知道了 i<n 的狀況,那咱們就能夠對全部狀況進行遍歷:
"(" + 【i=p時全部括號的排列組合】 + ")" + 【i=q時全部括號的排列組合】
其中 p + q = n-1,且 p q 均爲非負整數。
事實上,當上述 p 從 0 取到 n-1,q 從 n-1 取到 0 後,全部狀況就遍歷完了。
注:上述遍歷是沒有重複狀況出現的,即當 (p1,q1)≠(p2,q2) 時,按上述方式取的括號組合必定不一樣。
代碼實現:
LinkedList<LinkedList<String>> result = new LinkedList<>(); if (n == 0) { return new LinkedList<>(); } LinkedList<String> list0 = new LinkedList<>(); list0.add(""); result.add(list0); LinkedList<String> list1 = new LinkedList<>(); //當n=1時,只有一組括號 list1.add("()"); result.add(list1); for (int i = 2; i <= n; i++) { LinkedList<String> temp = new LinkedList<>(); for (int j = 0; j < i; j++) { List<String> str1 = result.get(j); List<String> str2 = result.get(i - 1 - j); for (String s1 : str1) { for (String s2 : str2) { String el = "(" + s1 + ")" + s2; temp.add(el); } } } result.add(temp); } return result.get(n);