22. 括号生成

在这里插入图片描述
就是一个dfs的过程,取或者不取,我们用两个值分别记录左右括号的数量,一开始都设为0,这里的回溯是自动回溯,如果是对tmp传引用的话就要弹出当前最后一位。如果是传参当return后,tmp回归到上一状态。dfs内部如果左右括号的数量都等于n,就将tmp加入结果数组,并return。如果左边的数量<n,就递归搜索,参数就是left+1,right不变,tmp就是tmp加上"("。如果right不等于n并且right的数量严格小于left,就dfs右边的括号,必须严格小于,等于都不行

class Solution {
public:
    void dfs(int left, int right, int n,string tmp){
        if(left == n && right == n){
            res.push_back(tmp);
            return;
        }
        //因为在一开始就有判断,所以不会越界,就不用判断left>n了
        //递归就是取和不取的过程,先取左肯定不会有错
        if(left != n){
            dfs(left+1,right,n,tmp+"(");
        }
        if(right != n && right<left){
            dfs(left,right+1,n,tmp+")");
        }
    }

    vector<string> generateParenthesis(int n) {
        //右边的符号数量不能超过左边的
        if(n < 0) return res;
        //就是取或者不取的情况,最后生成的字符串长度一定是2n,每走一步判断当前的左边有几个,如果左边>右边,那么左右都可以取,如果左=右,只能取左,用dfs来解决
        int left = 0, right = 0;
        string tmp = "";
        dfs(left,right,n,tmp);
        return res;
    }
private:
    vector<string> res;
};

想清楚什么时候可以生成左,什么时候可以生成右。左只要不超过n都可以生成,右只要不超过左就可以生成

class Solution {
public:
    void dfs(int& n, int left, int right, string tmp){
        if(left == n && right == n){
            res.push_back(tmp);
            return;
        }
        //什么情况可以生成(,什么情况可以生成),画一下树形图就知道了
        //左边永远大于等于右边,只要考虑左边的个数就行了吧?
        //左只要在没有越界的情况下随便取,无论右有几个
        //右边只能在左大于右的时候才能取
        //两者不是if-else关系,就和bfs树一样,左边取不取和右边取不取没关系!左边取了,右边在满足条件的情况下也可以取
        if(left!=n){
            dfs(n,left+1,right,tmp+'(');
        }
        //left最大等于n,right<left和right小于n合并就是right<left
        if(right < left){
            dfs(n,left,right+1,tmp+')');
        }
    }
    vector<string> generateParenthesis(int n) {
        if(n == 0) return res;
        dfs(n,0,0,"");
        return res;
    }
private:
    vector<string> res;
};
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:C马雯娟 返回首页