递归回溯分治--08-括号生成[中等]

该博客探讨了如何使用递归算法生成所有有效括号组合,以解决力扣(LeetCode)上的一个问题。示例展示了当给定括号对数为n时,如何通过限制左括号和右括号的放置条件来确保括号字符串的合法性。最终的解决方案是一个C++实现的递归函数,它能够正确生成所有有效括号序列。
摘要由CSDN通过智能技术生成

力扣

题目

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

示例 1:

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

示例 2:

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

 提示:1 <= n <= 8

思路

不考虑有效性,n组括号共2*n位,每个位置有2种可能,即‘(’或‘)’。因此共有2^(2*n)种可能。可以先尝试递归生成这些结果。

void generateTemp(string item,int n,vector<string> &ret)
{
	if (item.size() == 2*n) {
		ret.push_back(item); //当item长度足够时 结束
		return;
	}
	generateTemp(item + "(", n, ret);
	generateTemp(item + ")", n, ret);
}

void test02()
{
	vector<string> ret;
	generateTemp("", 2, ret);
	for (vector<string>::iterator it = ret.begin(); it != ret.end(); it++)
		cout << (*it) <<endl;
	cout << endl;
}

现在要考虑将合法的结果找出来。

可以看到结果中,只有标红的两个是合法的结果。因此在递归中需要添加条件,寻找合法的结果。

  1. 左括号或右括号的数量不能超过n
  2. 只有先放一个左括号,才能再放一个右括号。

答案

class Solution {
public:
	vector<string> generateParenthesis(int n) {
		vector<string> ret;
		generateTemp("", n, n, ret);
		return ret;
	}

	void generateTemp(string item, int left,int right, vector<string>& ret)
	{
		//left和right用于计数 当都为0时 表示生成结束
		if (left == 0 && right == 0) { 
			ret.push_back(item); //当item长度足够时 结束
			return;
		}
		if (left > 0) //左括号计数>0时 放置 
			generateTemp(item + "(", left - 1, right, ret); //放置后-1
		if (left < right) //右括号计数比左括号大时 放置
			generateTemp(item + ")", left, right - 1, ret); //放置后-1
	}
};
#include <iostream>
#include <set>
#include <string>
#include <vector>
#include <stack>
#include <algorithm> //标准算法的头文件
using namespace std;

class Solution {
public:
	vector<string> generateParenthesis(int n) {
		vector<string> ret;
		generateTemp("", n, n, ret);
		
		for (vector<string>::iterator it = ret.begin(); it != ret.end(); it++)
			cout << (*it) << endl;
		cout << endl;
		return ret;
	}

	void generateTemp(string item, int left,int right, vector<string>& ret)
	{
		//left和right用于计数 当都为0时 表示生成结束
		if (left == 0 && right == 0) { 
			ret.push_back(item); //当item长度足够时 结束
			return;
		}
		if (left > 0) //左括号计数>0时 放置 
			generateTemp(item + "(", left - 1, right, ret); //放置后-1
		if (left < right) //右括号计数比左括号大时 放置
			generateTemp(item + ")", left, right - 1, ret); //放置后-1
	}
};

void test01()
{
	Solution solution;
	//vector<int>v0 = { 1,2,2 };

	vector<string> ret = solution.generateParenthesis(3);
	cout << ret.size() << endl;
	//迭代器遍历
	for (vector<string>::iterator it = ret.begin(); it != ret.end(); it++) 
		cout << (*it) << "\t";
	cout << endl;
	
}


int main()
{
	test01();

	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值