【leetcode】leetcode22括號生成通過程式碼及題解

精緻又勤奮的碼農發表於2020-10-04

題目描述

數字 n 代表生成括號的對數,請你設計一個函式,用於能夠生成所有可能的並且 有效的 括號組合。
示例:
輸入:n = 3
輸出:[
“((()))”,
“(()())”,
“(())()”,
“()(())”,
“()()()”
]

通過的程式碼

我的程式碼:

class Solution {
public:
    int left_n;
    int right_n;
    stack<char> input;
    vector<char> per_compose;
    vector<string>ans;
    vector<string> generateParenthesis(int n) {
        if(n==0)
        return ans;
        left_n=n-1;
        right_n=n;
        input.push('(');
        per_compose.push_back('(');
        dfs(n,1);
        return ans;
    }
    void dfs(int n,int depth)
    {
        if(per_compose.size()==(2*n))
        {
            string s;
            for(int i=0;i<per_compose.size();i++)
            s+=per_compose[i];
            ans.push_back(s);
            return ;
        }
        if(right_n>=1)
        {
            if(!input.empty()&&input.top()=='(')
            {
                per_compose.push_back(')');
                right_n--;
                input.pop();
                dfs(n,depth+1);
                per_compose.pop_back();
                right_n++;
                input.push('(');
            }
        }
        if(left_n>=1)
        {
            per_compose.push_back('(');
            input.push('(');
            left_n--;
            dfs(n,depth+1);
            per_compose.pop_back();
            input.pop();
            left_n++;
        }
    }
};

網上優秀的程式碼:

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        vector<string> res;
        func(res, "", 0, 0, n);
        return res;
    }
    
    void func(vector<string> &res, string str, int l, int r, int n){
        if(l > n || r > n || r > l) return ;
        if(l == n && r == n) {res.push_back(str); return;}
        func(res, str + '(', l+1, r, n);
        func(res, str + ')', l, r+1, n);
        return;
    }
};

解題思路

解題思路就是dfs。看到題目的第一反應也是用dfs解決,因為感覺就是列出所有的組合,從中尋找滿足要求的組合,只能用圖遍歷演算法。然後回想起來,當遇到的問題是全排列問題的時候,最好是選擇dfs而不是bfs,因為可以省空間,所以選擇dfs。
看了看我自己的程式碼和大佬的程式碼。同樣都是dfs,大佬的程式碼就要簡潔很多。主要是省掉了很多的變數,像我寫的時候,用了left_n儲存(括號的使用情況,right_n儲存)括號的使用情況,還有per_compose這個vector儲存每一種組合方式。但是其實這些變數都可以通過dfs函式的引數體現出來,完全不用自己再重新定義變數。還有中間的剪枝,下面這份程式碼直接用if(l > n || r > n || r > l) return ;就考慮到了所有的剪枝。r > l這個判斷條件就很精妙,省掉了很多的程式碼量。

相關文章