《Leetcode刷题笔记》22. 括号生成

        解决一个问题有好多步,每一步都有多个选项时,用回溯算法,回溯算法是一种树上的dfs,这里的树指的是递归树。回溯大致可分为3类:1.组合、子集 (无序)2.排列(有序)3.搜索
        例如本题,我们分2n步,每一步有两个选项:左括号or右括号,所以使用回溯算法,本题属于组合问题。


按照回溯算法六步骤:
1.画递归树,找状态变量
2.判断结束条件
3.找出选择列表
4.判断枝剪
5.递归进入下一层
6.撤销

再回到本问题,首先显而易见结束条件就是凑够了n对括号,即2n个括号,可以判断字符串长度==2n来判断是否结束。选择列表每次都能选一个左括号或者右括号,但是(重点来了)!!!

1.左括号的数量不能大于n,否则没有足够的右括号与之闭合
2.每一步的右括号数量不能大于左括号数量例如:"())"是一种错误的括号组合。

第一条是对左括号的限制,第二点是对右括号的限制。
明白这两点之后,就知道我们需要知道当前已生成序列中左括号的数量,知道左括号数量,右括号数量也知道了,所以参数中加入一个int变量来记录左括号数量。每次判断前面两条是否满足,来决定是否添加左、右括号。

综上本题的6步策略:
1.状态变量:左括号数量
2.结束条件已生成长度==2n
3.选择列表:"(" , ")"
4.枝剪不符合上文两条的选项
5.递归下一层
6.撤销

代码

class Solution {
public:
    vector<string> ans;
    string s;
    vector<string> generateParenthesis(int n) {
        dfs(0,n);
        return ans;
    }
    void dfs(int left_num,int n){  //s.size()-left_num=right_num
        if(s.size()==2*n){
            ans.push_back(s);
            return;
        }
        if(left_num+1<=n){//左括号数量不大于n
            s+="(";//选择
            dfs(left_num+1,n);//递归
            s.erase(s.size()-1,1);//撤销
        }
        if(s.size()-left_num < left_num){//右括号数量<左括号
            s+=")";//选择
            dfs(left_num,n);//递归
            s.erase(s.size()-1, 1);//撤销
        }
    }
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值