力扣Hot100-22 括号生成【递归三步法】

力扣Hot100-22 括号生成

全部刷题与学习记录

【C++刷题学习笔记目录】

原题目

题目地址:22. 括号生成

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

示例 1:

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

示例 2:

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

考查知识点

递归应用

好的解法

参考公众号【数据结构与算法】的一种深度优先遍历解法。

首先观察括号组合有两种规律:

  1. 任意括号(满足题目条件)一定是 左括号数量 = 右括号数量
  2. 在任意括号中的任意位置(截断到当前位置),一定是 左括号数量 > 右括号数量

使用递归三步法来分析这个问题:

  1. 递归函数参数及返回值: 需要遍历所有情况时不需要返回值,需要找某条路径的时候才需要返回值。本题要遍历所有组合状况,因此不需要返回值。需要一个字符串数组res记录所有满足条件的字符串,需要leftright两个计数器表示剩下的左右括号数量,需要一个字符串curStr表示当前组合
  2. 函数结束条件: 根据left与right一共有三种情况。①left == 0 && right == 0:所有左右括号全部匹配完毕,没有剩余,将curStr加入res;②left > right:说明curStr中右括号数量超过左括号,不合法;③left < 0 || right < 0:剩余括号已经分配完,不能继续分配
  3. 递归循环逻辑,就是不断分配左右括号,记得将对应的括号加入curStr
#include<iostream>
#include <vector>

using namespace std;

class Solution {
    
    
private:
    vector<string> res;
    void dfs(int left, int right, string curStr) {
    
    
        if (left == 0 && right == 0) {
    
    
            res.push_back(curStr);
            return;
        }
        if (left < 0 || right < 0) {
    
    //左括号或者右括号选完了
            return;
        }
        else if (left > right) {
    
    //剩余的左括号多
            return;
        }
        
        //加左括号
        dfs(left - 1, right, curStr + "(");
        //加右括号
        dfs(left, right - 1, curStr + ")");
    }
public:
    vector<string> generateParenthesis(int n) {
    
    
        dfs(n, n, "");

        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_44484715/article/details/115741330
今日推荐