括号生成--力扣

Posted 穿迷彩服的鲨鱼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了括号生成--力扣相关的知识,希望对你有一定的参考价值。


前言

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


一、示例

示例 1:

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

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

提示:

1 <= n <= 8

二、代码解析

1.暴力解法

代码如下(示例):

/// <summary>
/// 判断当前是否是有效括号
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
bool valid(const string& str)
{
	int balance = 0;
	for (auto c : str)
	{
		if (c == '(')
		{
			++balance;
		}
		else
		{
			--balance;
		}
		if (balance < 0)
		{
			return false;
		}
	}
	return balance == 0;
}

/// <summary>
/// 生成所有括号排序可能
///	我们可以生成所有可能,然后检查每一个是否是有效括号
/// </summary>
/// <param name="current"></param>
/// <param name="n"></param>
/// <param name="result"></param>
void generateAll(string& current, int n, vector<string>& result)
{
	if (n == current.size())
	{
		if (valid(current))
		{
			result.emplace_back(current);
		}
		return;
	}

	current += ")";
	generateAll(current, n, result);
	current.pop_back();
	current += "(";
	generateAll(current, n, result);
	current.pop_back();
}

vector<string> generateParenthesis(int n)
{
	vector<string> result;
	string currentStr;
	generateAll(currentStr, 2 * n, result);
	return result;
}

结果

在这里插入图片描述

2.回溯法

代码如下(示例):

//改进:如果左括号数量不大于 n,我们可以放一个左括号。如果右括号数量小于左括号的数量,我们可以放一个右括号。
void backtrack(string& cur, int n, vector<string>& ans, int open, int close)
{
	if (cur.size() == n * 2)
	{
		ans.push_back(cur);
		return;
	}
	if (open < n)
	{
		cur.push_back('(');
		backtrack(cur, n, ans, open+1, close);
		cur.pop_back();
	}
	if (close < open)
	{
		cur.push_back(')');
		backtrack(cur, n, ans, open, close+1);
		cur.pop_back();
	}
}

vector<string> generateParenthesis(int n)
{
	vector<string> result;
	string currentStr;
	backtrack(currentStr, n, result, 0, 0);
	return result;
}

结果

在这里插入图片描述

测试

代码如下(示例):

#include<vector>
#include <iostream>
using namespace std;

/*暴力解法
/// <summary>
/// 判断当前是否是有效括号
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
bool valid(const string& str)
{
	int balance = 0;
	for (auto c : str)
	{
		if (c == '(')
		{
			++balance;
		}
		else
		{
			--balance;
		}
		if (balance < 0)
		{
			return false;
		}
	}
	return balance == 0;
}

/// <summary>
/// 生成所有括号排序可能
///	我们可以生成所有可能,然后检查每一个是否是有效括号
/// </summary>
/// <param name="current"></param>
/// <param name="n"></param>
/// <param name="result"></param>
void generateAll(string& current, int n, vector<string>& result)
{
	if (n == current.size())
	{
		if (valid(current))
		{
			result.emplace_back(current);
		}
		return;
	}

	current += ")";
	generateAll(current, n, result);
	current.pop_back();
	current += "(";
	generateAll(current, n, result);
	current.pop_back();
}*/
//改进:如果左括号数量不大于 n,我们可以放一个左括号。如果右括号数量小于左括号的数量,我们可以放一个右括号。
void backtrack(string& cur, int n, vector<string>& ans, int open, int close)
{
	if (cur.size() == n * 2)
	{
		ans.push_back(cur);
		return;
	}
	if (open < n)
	{
		cur.push_back('(');
		backtrack(cur, n, ans, open+1, close);
		cur.pop_back();
	}
	if (close < open)
	{
		cur.push_back(')');
		backtrack(cur, n, ans, open, close+1);
		cur.pop_back();
	}
}

vector<string> generateParenthesis(int n)
{
	vector<string> result;
	string currentStr;
	backtrack(currentStr, n, result, 0, 0);
	return result;
}

int main()
{
	vector<string> result = generateParenthesis(3);
	for (int i = 0; i < result.size(); i++)
	{
		cout << result[i] << " ";
	}
	return 0;
}

结果

在这里插入图片描述


总结

在这里插入图片描述

以上是关于括号生成--力扣的主要内容,如果未能解决你的问题,请参考以下文章

力扣刷题:括号生成(java实现)

力扣刷题:括号生成(java实现)

力扣22. 括号生成

22.括号生成

力扣leetcode1190. 反转每对括号间的子串

leetcode-22括号生成