括号生成--力扣
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;
}
结果
总结
以上是关于括号生成--力扣的主要内容,如果未能解决你的问题,请参考以下文章