LeetCode刷题--- 括号生成

个人主页: 元清加油_【C++】,【C语言】,【数据结构与算法】-CSDN博客

个人专栏

力扣递归算法题

http://t.csdnimg.cn/yUl2I

【C++】

http://t.csdnimg.cn/6AbpV

数据结构与算法

http://t.csdnimg.cn/hKh2l


前言:这个专栏主要讲述递归递归、搜索与回溯算法,所以下面题目主要也是这些算法做的

我讲述题目会把讲解部分分为3个部分:
1、题目解析

2、算法原理思路讲解

3、代码实现


括号生成

题目链接:括号生成

题目

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

示例 1:

复制代码
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

示例 2:

复制代码
输入:n = 1
输出:["()"]

提示:

  • 1 <= n <= 8

解法

题目解析

题目的意思非常简单,给定我们一个数字 n 用于能够生成所有可能的并且 有效的括号组合。

示例 1:

复制代码
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

算法原理思路讲解

我们要解决这道题目,首先要知道的是什么是有效的括号,首先有效的括号应该符合下面两点

  • 总的左括号数量等于总的右括号数量(左括号数量 == 总的右括号数量)
  • 从头开始的任意一个子串,总的左括号的数量都大于等于总的右括号的数量

从左往右进⾏递归,在每个位置判断放置左右括号的可能性,若此时放置左括号合理,则放置左括号继续进⾏递归,右括号同理。⼀种判断括号是否合法的⽅法:从左往右遍历,左括号的数量始终⼤于等于右括号的数量,并且左括号的总数量与右括号的总数量相等。因此我们在递归时需要进⾏以下判断:

  • 放⼊左括号时需判断此时左括号数量是否⼩于字符串总⻓度的⼀半(若左括号的数量⼤于等于字符串⻓度的⼀半时继续放置左括号,则左括号的总数量⼀定⼤于右括号的总数量);
  • 放⼊右括号时需判断此时右括号数量是否⼩于左括号数量。

并且由题目意思可以的到,需要填入的空为 2n,那么我们便可以设计出决策树来了。

我们可以一共选择 2n 次,将不符合有效的括号的剪枝掉。

一、画出决策树

以 n=2 为例子

决策树就是我们后面设计函数的思路


二、设计代码

(1)全局变量

复制代码
int left,right,sum;
string path;
vector<string> ret;
  • left(当前状态的字符串中的左括号数量)
  • right(当前状态的字符串中的右括号数量)
  • sum(总的左右括号最多的数量)
  • path(记录路径的左右括号)
  • ret(存放所有有效括号的可能)

(2)设计递归函数

复制代码
void dfs();
  • 参数:无;
  • 返回值:⽆;
  • 函数作⽤:查找所有合理的括号序列并存储在答案列表中

递归流程如下:

  1. 递归结束条件:当前状态右括号⻓度与 n 相等,记录当前状态并返回;
  2. 若此时左括号数量⼩于 n ,则在当前状态的字符串末尾添加左括号并继续递归, 递归结束撤销添加操作;
  3. 若此时右括号数量⼩于左括号数量(右括号数量可以由当前状态的字符串⻓度减去左括号数量求 得),则在当前状态的字符串末尾添加右括号并递归,递归结束撤销添加操作;

以上思路讲解完毕,大家可以自己做一下了


代码实现

  • 空间复杂度:O(n),除了答案数组之外,我们所需要的空间取决于递归栈的深度,每一层递归函数需要 O(1) 的空间,最多递归 2n 层,因此空间复杂度为 O(n)

    class Solution {
    public:
    int left,right,sum;
    string path;
    vector ret;

    复制代码
      void dfs()
      {
          if (right == sum)
          {
              ret.push_back(path);
              return;
          }
    
          if (left < sum)
          {
              path.push_back('(');
              left++;
              dfs();
              path.pop_back();
              left--;
          }
    
          if (right < left)
          {
              path.push_back(')');
              right++;
              dfs();
              path.pop_back();
              right--;
          }
    
      }
      vector<string> generateParenthesis(int n) 
      {
          sum = n;
          dfs();
    
          return ret;
      }

    };

相关推荐
鹿角片ljp4 分钟前
LeetCode 64:最小路径和复盘|二维 DP 与 ACM 模式完整写法
java·数据结构·算法
彧azz1 小时前
算法设计与分析:贪心与动态规划
数据结构·学习·算法·贪心算法·动态规划
Beyond_System|系统之外2 小时前
【学编程】Python基础编程题100道(21-60)
开发语言·python·算法
漂流瓶jz4 小时前
UVA-1442 洞穴 题解答案代码 算法竞赛入门经典第二版
c++·算法·题解·aoapc·算法竞赛入门经典·uva
圣保罗的大教堂4 小时前
leetcode 835. 图像重叠 中等
leetcode
叠层归一研究院5 小时前
基于极限自指的叠层归一宇宙结构理论——无元外部封闭系统的内生区分模型
人工智能·经验分享·算法·agi
Selvaggia6 小时前
Diffusion Model 的基本原理与模型架构
算法
wabs6668 小时前
关于二叉树【力扣572.另一棵树的子树的思考】
数据结构·c++·算法·leetcode·二叉树
hanlin038 小时前
刷题笔记:力扣第41题-缺失的第一个正数
笔记·算法·leetcode
shehuiyuelaiyuehao8 小时前
算法50,分治归并,数组中的逆序对
java·算法