LeetCode 算法:括号生成 c++

原题链接🔗括号生成
难度:中等⭐️⭐️

题目

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

示例 1:

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

示例 2:

输入:n = 1
输出:[“()”]

提示:

1 <= n <= 8

递归

递归是一种在计算机科学中常用的编程技术,它允许函数调用自身。递归函数通常用于解决可以被分解为相似子问题的问题。递归的关键点在于找到问题的基本情况(base
case)和递归步骤(recursive case)。

  • 递归的基本概念

    1. 基本情况(Base Case):递归函数必须有一个或多个停止条件,这些条件不需要进一步递归调用。当达到这些条件时,函数将返回一个值。
    2. 递归步骤(Recursive Case):在递归步骤中,函数会调用自身,并且每次调用都会使问题更接近基本情况。
  • 递归的步骤

    1. 定义问题:首先定义需要解决的问题。
    2. 确定基本情况:找出问题的基本情况,即不需要进一步递归调用的情况。
    3. 递归调用:在函数中调用自身,每次调用都使问题更接近基本情况。
    4. 组合结果:将递归调用的结果组合起来,形成最终的解决方案。
  • 递归的应用

    • 图形和树的遍历(如深度优先搜索)
    • 排序算法(如快速排序和归并排序)
    • 动态规划问题
    • 字符串处理(如字符串匹配和编辑距离)
  • 递归的注意事项

    • 避免无限递归:确保递归调用能够达到基本情况,避免无限递归。
    • 优化递归:递归可能会导致大量的重复计算,可以通过记忆化递归来优化性能。
    • 栈溢出:递归深度过大可能会导致栈溢出,因此需要考虑递归的深度。
  • 示例:计算阶乘 下面是一个使用递归计算阶乘的示例代码:

 #include <iostream>
> 
> int factorial(int n) {
>     if (n == 0) { // 基本情况
>         return 1;
>     } else { // 递归步骤
>         return n * factorial(n - 1);
>     } }
> 
> int main() {
>     int n;
>     std::cout << "Enter a number: ";
>     std::cin >> n;
>     std::cout << "Factorial of " << n << " is " << factorial(n) << std::endl;
>     return 0; } 

在这个示例中:

  • factorial 函数是一个递归函数,它计算一个数的阶乘。
  • n 等于 0 时,函数返回 1(基本情况)。
  • 否则,函数返回 n * factorial(n - 1)(递归步骤)。

递归是一种强大的工具,但也需要谨慎使用,以避免潜在的问题。

回溯算法

回溯算法是一种通过试错来解决问题的算法,它尝试分步地去解决一个问题。在分步解决问题的过程中,如果某一步不符合要求,就会回退到上一步(回溯),然后选择另外一种方式继续尝试。回溯算法通常用于解决组合问题、排列问题、生成问题等。

  • 回溯算法的基本思想
    • 选择:从问题的候选解中选择一个解,通常是一个部分解。
    • 扩展:将选择的解扩展为更接近最终解的形式。
    • 剪枝:在扩展过程中,如果发现当前的解不可能产生最终解,就停止继续扩展,回退到上一步。
    • 回溯:当扩展到某一步发现当前路径不能得到解时,就回退到上一步,重新选择其他候选解继续尝试。
  • 回溯算法的步骤
    • 定义问题:明确需要解决的问题,并确定问题的候选解。
    • 确定候选解:列出所有可能的候选解。
    • 递归函数:设计一个递归函数,用于尝试不同的候选解。
    • 剪枝:在递归过程中,根据问题的特点,剪去那些不可能产生解的候选解。
    • 回溯:当发现当前路径不能得到解时,回退到上一步,重新选择候选解。
  • 回溯算法的应用
    • 八皇后问题
    • 素数生成
    • 括号生成
    • 数独问题
    • 图的着色问题

题解

  1. 解题思路

LeetCode 上的“括号生成”问题是一个经典的递归问题,主要考察的是回溯算法。这个问题要求你生成所有可能的括号组合,确保每个括号都有一个匹配的配对。

  • 理解问题:首先需要理解什么是有效的括号组合。有效的括号组合意味着每个左括号 ‘(’ 都有一个对应的右括号 ‘)’,并且右括号不能在左括号之前。
  • 递归方法:使用递归方法生成括号。递归的基本思路是:
    • 从左到右逐个添加括号。
    • 在每一步,可以选择添加左括号 ‘(’ 或者右括号 ‘)’。
    • 确保在添加右括号 ‘)’ 之前,左括号 ‘(’ 的数量不少于右括号的数量。
  • 回溯:每次递归时,尝试添加一个括号,然后回溯到上一步,尝试添加另一种括号。这样能够生成所有可能的组合。
  • 终止条件:当生成的括号数量达到 2n 时,返回当前生成的字符串,因为 n 个左括号和 n 个右括号已经完全匹配。
  1. c++ demo:
#include <iostream>
#include <vector>
#include <string>

class Solution {
public:
    std::vector<std::string> generateParenthesis(int n) {
        std::vector<std::string> result;
        backtrack(result, "", 0, 0, n);
        return result;
    }

private:
    void backtrack(std::vector<std::string>& result, std::string current, int open, int close, int max) {
        if (current.length() == 2 * max) {
            result.push_back(current);
            return;
        }

        if (open < max) {
            backtrack(result, current + '(', open + 1, close, max);
        }

        if (close < open) {
            backtrack(result, current + ')', open, close + 1, max);
        }
    }
};

int main() {
    Solution solution;
    int n;
    std::cout << "Enter the number of pairs of parentheses: ";
    std::cin >> n;

    std::vector<std::string> parentheses = solution.generateParenthesis(n);
    std::cout << "Total combinations: " << parentheses.size() << std::endl;
    for (const std::string& s : parentheses) {
        std::cout << s << std::endl;
    }

    return 0;
}
  • 输出结果:

Enter the number of pairs of parentheses: 4
Total combinations: 14
(((())))
((()()))
((())())
((()))()
(()(()))
(()()())
(()())()
(())(())
(())()()
()((()))
()(()())
()(())()
()()(())
()()()()

  1. 代码仓库地址generateParenthesis

相关推荐

  1. LeetCode 算法括号生成 c++

    2024-07-18 05:58:02       22 阅读
  2. LeetCode 22 括号生成

    2024-07-18 05:58:02       62 阅读
  3. [leetcode] 22. 括号生成

    2024-07-18 05:58:02       58 阅读
  4. LeetCode-22.括号生成

    2024-07-18 05:58:02       43 阅读
  5. LeetCode 22. 括号生成

    2024-07-18 05:58:02       50 阅读
  6. leetcode-22. 括号生成

    2024-07-18 05:58:02       24 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-18 05:58:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-18 05:58:02       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-18 05:58:02       58 阅读
  4. Python语言-面向对象

    2024-07-18 05:58:02       69 阅读

热门阅读

  1. Apache Omid TSO 组件源码实现原理

    2024-07-18 05:58:02       21 阅读
  2. php 方法追踪其被调用的踪迹

    2024-07-18 05:58:02       20 阅读
  3. 山东航空小程序查询

    2024-07-18 05:58:02       23 阅读
  4. 怎么查看占用端口的 PID

    2024-07-18 05:58:02       20 阅读
  5. 算法1.快速幂【a^b、(a^b)%p】

    2024-07-18 05:58:02       22 阅读
  6. 第三节SHELL脚本中的变量与运算(2.2)

    2024-07-18 05:58:02       20 阅读
  7. nng协议nni_posix_resolv_sysinit()系统初始化

    2024-07-18 05:58:02       22 阅读
  8. Tensor列表索引本质

    2024-07-18 05:58:02       20 阅读
  9. 社会科学战线

    2024-07-18 05:58:02       22 阅读
  10. 资源管理大师:如何在Gradle中配置资源目录

    2024-07-18 05:58:02       25 阅读
  11. derivate_gauss 将图像与高斯函数的导数卷积

    2024-07-18 05:58:02       22 阅读
  12. 掌握Xcode Storyboard:iOS UI设计的可视化之旅

    2024-07-18 05:58:02       22 阅读