22. 括號生成

題目:

給出 n 代表生成括號的對數,請你寫出一個函數,使其能夠生成所有可能的並且有效的括號組合。

例如,給出 n = 3,生成結果爲:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]

思路:

核心思想是 組合算法的應用。

首先介紹組合算法。從m個元素取n個元素,不考慮取出順序。

一種代碼實現:(基於深度遍歷,此方法爲倒序遍歷)

參考博客:https://blog.csdn.net/weixin_40571331/article/details/82848341


void dfs(int n, int x) { 
	if (x == r) { //遞歸跳出條件:當數組存儲的數字達到r時輸出
		for (int i = 0; i < r; i++) 
			printf("%d", a[i]);
		printf("\n");
	}
	for (int i = n; i > 0; i--) {
		a[x] = i;
		dfs(i-1, x+1);
	}
}

此問題可簡化爲從2*n個元素中選擇n個元素爲( ,其他元素爲),簡單思考可以得出,第一個元素必爲(,最後一個元素必爲)。即問題變爲從2*n-2個元素中選擇n-1個元素

但並不是每種組合都符合要求,括號匹配時刻必須滿足( 的數量不小於 )的數量。可以在生成字符串時對括號進行計數。

 

代碼:

class Solution {
    static List<String> list = null;
    static int len;
    public List<String> generateParenthesis(int n) {
        list = new ArrayList();
        len = n*2-2;
        int[] a = new int[n-1];
        dfs(n*2-2,0,n-1,a);
        return list;
    }
    
    public static void dfs(int n, int x,int r,int[] a) {
        if (x == r) { //遞歸跳出條件:當數組存儲的數字達到r時輸出
            StringBuffer sb = new StringBuffer();
            int l=1,m=0;
            sb.append('(');
            int j=0;
            for (int i = 0; i < len; i++){
                int t = 0;
                if(j<r){
                    t = len-a[j]+1;
                }
                if(i+1==t){
                    l++;
                    j++;
                    sb.append("(");
                }else{
                    m++;
                    sb.append(")");
                }
                if(l<m) return;

            }
            sb.append(')');
            list.add(sb.toString());
            return ;
        }
        for (int i = n; i > 0; i--) {
            a[x] = i;
            dfs(i-1, x+1,r,a);
        }
    }
}

注:leetcode中慎用類變量,上例中arraylist若不每次在generateParenthesis()方法中進行初始化,則會出現上個測試用例的結果仍然在下個測試用例的list中,算是一個小bug吧

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