1. 程式人生 > 實用技巧 >LeetCode Notes_#22_括號生成

LeetCode Notes_#22_括號生成

LeetCode Notes_#22_括號生成

LeetCode

Contents

題目


解答

方法1:暴力遞迴

給出括號對數n之後,就確定了括號組合的字串長度必然是2n,我們可以通過暴力遞迴的方式,在2n個位置上放置'('或者')',得到所有的排列序列,然後逐個判斷每個排列序列是否是正確的,將正確的排列序列加入到結果列表當中。

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> combinations = new
ArrayList<>(); generateAll(new char[2*n], 0, combinations); return combinations; } public void generateAll(char[] current, int pos, List<String> result){ //出口條件:pos指標指向current的末尾之後一個位置(末尾是current.length - 1) if(pos == current.length){ if
(valid(current)){ result.add(new String(current)); } //遞推過程:在current陣列末尾位置新增'('或者')',然後進行遞迴呼叫,在下一個位置pos + 1繼續新增'('或者')' //這個過程中並不考慮'('和')'之間的數量以及配對是否是正確的,而是在將整個字串都生成後,才判斷這個字串是否是正確配對的 }else{ current[pos] = '('; generateAll(current, pos + 1
, result); current[pos] = ')'; generateAll(current, pos + 1, result); } } //驗證一個排列序列是否正確 public boolean valid(char[] current){ int balance = 0; for(char c: current){ if(c == '('){ balance++; }else{ balance--; } if(balance < 0){ return false; } } return balance == 0; } }

複雜度分析

時間複雜度:,排列序列一共有個,對於每個排列序列,呼叫valid()方法進行驗證,其時間複雜度為
空間複雜度:,遞迴棧的深度是2n層。

方法2:回溯

在暴力遞迴法當中,我們其實生成了很多無效的排列序列,但是都要等到最後才能判斷出它們是無效的。更優的方法應該是在構造序列的時候,就進行剪枝,對於已經確認無效的序列,提前將其排除(剪枝)。
回溯法裡邊的回溯,指的就是撤銷選擇這一過程,無論這一次選擇的結果是不是正確的,我們都需要回溯回去,嘗試其他的可能性。

class Solution {
    public List<String> generateParenthesis(int n) {
        List<String> ans = new ArrayList<>();
        backtrack(ans, new StringBuilder(), 0, 0, n);
        return ans;
    }

    // left,right代表左括號,右括號出現的次數
    private void backtrack(List<String> ans, StringBuilder cur, int left, int right, int n){
        //出口條件:長度達到2n,可以保證結果是正確的,直接加入結果列表當中
        if(cur.length() == 2*n){
            ans.add(cur.toString());
            return;
        }
        //左括號數量<n,可以繼續新增左括號
        if(left < n){
            cur.append('(');
            backtrack(ans, cur, left + 1, right, n);
            cur.deleteCharAt(cur.length() - 1);
        }
        //右括號的數量<左括號的數量,可以繼續新增右括號
        if(right < left){
            cur.append(')');
            backtrack(ans, cur, left, right + 1, n);
            cur.deleteCharAt(cur.length() - 1);
        }
    }
}

複雜度分析