1. 程式人生 > >【探索-中級演算法】生成括號

【探索-中級演算法】生成括號

在這裡插入圖片描述

得到全排列的組合,同時對於不符合要求的組合要剔除。

public List<String> generateParenthesis(int n) {
    List<String> result = new ArrayList<>();
    recall("", n, n,result);
    return result;
}
/**
 * @param leftCount 剩餘可用的左括號個數
 * @param rightCount 剩餘可用的右括號個數
 */
public void recall(String s, int
leftCount, int rightCount,List<String> result) { // 沒有括號可以進行組合了 if (leftCount == 0 && rightCount == 0) { result.add(s); } else { if (leftCount>0) { String tmp = s + '('; int newLeftCount = leftCount - 1; if (newLeftCount==rightCount)
{ // 當左右括號已經使用了同樣的個數,且目前為止組成的組合有效的話, // 才繼續遞迴,(剪枝,但是也增加了判斷的時間成本) // 因為有了這一步判斷,則當 leftCount 和 rightCount 都為 0 時肯定 // 是符合條件的 if (isEffective(tmp)) recall(tmp, newLeftCount, rightCount,result); } else { recall
(s + '(', newLeftCount, rightCount,result); } } if (rightCount>0) { String tmp = s + ')'; int newRightCount = rightCount - 1; if (newRightCount==leftCount) { if (isEffective(tmp)) recall(tmp, leftCount, newRightCount,result); } else { recall(tmp, leftCount, newRightCount,result); } } } } // 判斷組合是不是有效的 // 有效的定義就是對於 s[i] 如果是 '(',則在 s[j>i] 要存在 ')' 與之匹配 public boolean isEffective(String s) { if (s!=null&&s.length()>0) { Stack<Character> stack = new Stack<>(); char[] chars = s.toCharArray(); for (char c : chars) { if (c=='(') stack.push('('); else { if (stack.isEmpty()) return false; else stack.pop(); } } return true; } return false; }

根據網站提交記錄進一步的優化:

public List<String> generateParenthesis(int n) {
    List<String> result = new ArrayList<>();
    recall(n, n,"",result);
    return result;
}

/**
 * @param leftCount 剩餘可用的左括號個數
 * @param rightCount 剩餘可用的右括號個數
 */
public void recall(int leftCount,int rightCount,String s,List<String> result) {
    if (leftCount == 0 && rightCount == 0) {
        result.add(s);
    }
    if (leftCount>0) recall(leftCount - 1, rightCount, s + '(', result);
    if (rightCount>leftCount) recall(leftCount, rightCount - 1, s + ')', result);
}

可以發現,肯定是要先用 ‘(’,然後才能用 ')' 與前面的 '(' 匹配。