Leecode刷题热题HOT100(22)——括号生成

📋 前言

  • 🖱 博客主页:在下马农的碎碎念
  • 🤗 欢迎关注🔎点赞👍收藏⭐️留言📝
  • ✍ 本文由在下马农原创,首发于CSDN
  • 📆 首发时间:2021/12/25
  • 📅 最近更新时间:2021/12/25
  • 🤵 此马非凡马,房星本是星。向前敲瘦骨,犹自带铜声。
  • 📇 系列文章目录: 快点我呀,我是目录
  • 🙏作者水平有限,如发现错误,请留言轰炸哦!万分感谢!

在这里插入图片描述

二十多年前,我在不足二十平米的外婆家小院里蹦跶,感觉世界美好,我早已走遍。
——赵挺《外婆》

在这里插入图片描述
以下是正文

🍅 题目

数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。

示例 1:

输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

示例 2:

输入:n = 1
输出:["()"]

提示:

  • 1 <= n <= 8(重点!!!)

🍅 解题思路

🍏 方法一:回溯法穷举所有结果

解决这个问题首先要明确两点:

  • 1、一个符合条件的括号组合左括号数目等于右括号数量,则最后结果中括号总个数为2n
  • 2、在有效括号组合的前k位,对任意0<=k<=2n,都满足左括号数量大于等于右括号数量。
    然后就可以套用回溯算法的框架,穷举出所有结果。
    在本题中:结束条件为路径长度达到2n
    路径为左右括号的排列

穷举算法框架:

result = [];
void backtrace(路径,选择列表) {
	if(满足结束条件) {
		result.push_back(路径);
		return;
	}
	for(选择:选择列表) {
		做选择
		backtrace(路径,选择列表);
		撤销选择
	}
}

在穷举出所有可能之后,我们需要剔除所有不满足条件的括号组合,做一些剪枝,只返回满足条件的括号组合。

🍅 我的答案

class Solution {
public:
	// s为路径,即生成有效括号过程中的字符串,result存储所有符合条件的括号组合字符串
	// i为当前路径中已经有的左括号数量,j为当前路径中已经有的右括号数量
    void drawParenthesis(int i,int j,int n,string &s,vector<string> &result) {
    	// 路径长度达到2n,已生成有效括号
        if(s.size() == 2*n) {
            result.push_back(s); 
            return;
        } 
        // 左括号与右括号至多都为n
        if(i>n) {
            return;
        }
        // 在生成有效括号排列的过程中,左括号的数量始终大于等于右括号数量,否则就不能生成有效括号排列
        if(j > i){
            return;
        } else {
        	// 左括号数量小于n的时候,即可以生成左括号也可以生成右括号,但左括号数量等于n的时候,只能生成右括号
            if(i<n) {
            	// 选择生成左括号
                s.push_back('(');
                drawParenthesis(i+1,j,n,s,result);
                // 撤销选择
                s.pop_back();
            }
            // 选择生成右括号
            s.push_back(')');
            drawParenthesis(i,j+1,n,s,result);
            // 撤销选择
            s.pop_back();
        }
    }

    vector<string> generateParenthesis(int n) {
        string s = "";
        vector<string> result;
        // 初始状态为0个左括号,0个右括号
        drawParenthesis(0,0,n,s,result);
        return  result;
    }
};

🍅 优质解答

class Solution {
public:
    vector<string> res;
    void solve(int l, int r, int n, string cur) {
        if (l == n && r == n) {
            res.push_back(cur);
            return;
        }
        if (l < n)
            solve(l + 1, r, n, cur + "(");

        if (r < l)
            solve(l, r + 1, n, cur + ")");
    }
    vector<string> generateParenthesis(int n) {
        if (n == 0)
            return res;
        solve(0, 0, n, "");
        return res;
    }
};

🍅 知识积累

- 1、string也有push_back()方法和pop_back()方法,push_back()向字符串末尾添加一个字符,pop_back()为删除字符串末尾一个字符

🍅 题外话——论如何使用这一题的解答让电脑崩掉

题目给出的括号对数是1-8,在本地调试生成括号这道题时,突然想看看生成多一点的括号需要执行多长时间,随便输入了个23,结果杯具了,电脑直接卡死,一道小小的算法题就能轻易干崩电脑,以后写循环要注意一点,太可怕了!

在这里插入图片描述

随手点赞👍一次,运气增加一分哦🙏🙏🙏


注:本文中题目信息及优质解答来自力扣网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在下马农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值