LeetCode0022括号生成C++解法

题目描述

在这里插入图片描述

解法1[c++] 深搜

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        vector<string> res;
        dfs("", 0, n, &res);
        return res;
    }
    
    void dfs(const string& path, int m, int n, vector<string>* res) {
        // m 表示还可以用的右括号的数量,n 表示还可以用几个左括号的数量
        if (m == 0 && n == 0) {
            if (!path.empty()) res->push_back(path);
            return;
        }
    
        if (n > 0) dfs(path + '(', m + 1, n - 1, res);
        if (m > 0) dfs(path + ')', m - 1, n, res);
    }
};

解法2递归解决

注意几点

  • 1、注意递归的结束条件:左括号数小于右括号数目的时候,结束递归;
  • 2、当达到指定长度后也停止递归,且保存左右括号相等的情况作为结果,即筛掉((((((和(((())这些
class Solution {
public:
    vector<string> results;
    void reverse(int left,int right,string tmp,int n) {
        if(left < right) {
            return ;
        }
        
        
        if(tmp.size()==n) {
            if(left == right)
            {
                results.push_back(tmp);
            }
            return;
        }

        reverse(left+1,right,tmp+"(",n);
        reverse(left,right+1,tmp+")",n);
  
        
        
    }
    
    vector<string> generateParenthesis(int n) {
        string empty = "";
        reverse(0,0,empty,n*2);
        return results;
    }
};

解法3

与子集题比较像,对于全部所有子集,再选取合法的组合
计算:n组括号,一共2n个字符串,由于每个括号要么是左括号要么是右括号,因此一共有2^2n个子集
子集合法条件:

  • 1,左括号与右括号的数量不可以大于n,
  • 2,放一个左括号,才可以放右括号
    合法条件可以理解为递归生成子集终止条件
    因此递归终止条件为:
  • 1,左括号与右括号数量最多为n
  • 2,当左括号数量小于右括号,不可进行放置右括号的递归
    1,对于递归生成所有子集,想象一个二叉递归树,1空 2( 3) 2.1( 2.2) 3.1( 3.2)
void generate(std::string item, int n, std::vector<std::string> &result){
    if(item.size() == 2*n){//这里要理解,递归不是循环,这只是递归终止条件,不是循环判断
        result.push_back(item);//item用来存储生成的括号字符串,完成递归再存入结果
        return;
    }
    generate(item+'(', n, result);//添加(并且递归
    generate(item+')', n, result); //添加)并且递归
    }
其实这就是递归item由空字符串不断插入递归

2,本题对上述进行合法的子集筛选,其实即使改变递归限制条件

class Solution {
public:
    vector<string> generateParenthesis(int n) {
        std::vector<std::string> result;
        generate("", n, n, result);
        return result;
    }
private:
    void generate(std::string item, int left, int right,//item存储生成字符串
                  std::vector<std::string>& result){//left表示当前还可以放置左括号的数量
        if(left == 0 && right == 0){//这里递归终止条件就是左右都放完了,不可以size=2n
            result.push_back(item);
            return;
        }
        if(left > 0){//左括号随便放,放了过后,别忘了left-1
            generate(item+'(', left - 1, right, result);
        }
        if(left < right){//右括号要在左括号较多时候才可以放,即left是剩余可以放的括号要较小
            generate(item+')', left, right - 1, result);
        }      
    }
};

解法4

从1到n,每次都在原有的string上从头到尾插入"()",去掉重复的就是最后结果了

vector<string> generateParenthesis(int n) {
	set<string> base;
	base.insert("()");
	for (int i = 1; i < n; i++) {
		set<string> v;
		for (auto s : base) {
			for (int idx = 0; idx <= s.size(); idx++) {
				v.insert(string(s).insert(idx, "()"));
			}
		}
		v.swap(base);
	}

	vector<string> ret;
	for (auto &s : base)
		ret.push_back(s);
	return ret;
}

解法5

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;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值