大家好今天给大家分享下一道 LeetCode 中等难度 的题目[22. 括号生成]
题目
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
有效括号组合需满足:左括号必须以正确的顺序闭合。
示例 1:
输入:n = 3 输出:["((()))","(()())","(())()","()(())","()()()"] 示例 2:
输入:n = 1 输出:["()"]
分析
1.括号必须匹配且只有小括号
2.左括号可以一直加 但是不能大于等于n
3.右括号必须小于左括号个数
4.返回所有括号的数组
解法
1.递归
2.暴力
解法一:递归
思路
1.终止条件是left和right 都达到了n,则push答案到res中
2.根据情况去添加括号
1.添加左括号有2中情况
1.str为空
2.left 还没有到达n值
2.添加右括号
1.str最后一个元素是(
2.右括号数小于左括号数
3.返回res
*/
var generateParenthesis = function (n) {
const res = [];
function recursion(left, right, n, str) {
// 当left和right 都达到了n,则push答案到res中
if (left === n && right === n) {
res.push(str);
return;
}
// 添加括号
addParenthesis(left, right, n, str);
}
function addParenthesis(left, right, n, str) {
const strArr = str.split("");
const lastItem = strArr[strArr.length - 1];
/*
1.添加左括号有2中情况
1.str为空
2.left 还没有到达n值
*/
if (!strArr.length || left < n) {
recursion(left + 1, right, n, str + "(");
}
/*
2.添加右括号
1.str最后一个元素是(
2.右括号数小于左括号数
*/
if (lastItem === "(" || right < left) {
recursion(left, right + 1, n, str + ")");
}
}
recursion(0, 0, n, "");
return res;
};
/* 复杂度
时间 O(2^n)
空间 O(n)
*/
解法二:暴力
思路
1.生成所有的括号组合
2.通过判断括号是否有效来筛选
3.返回res
*/
var generateParenthesis = function (n) {
const res = [];
// 生成所有的括号组合
generateAll(n, "");
return res.filter((item) => {
return valid(item);
});
function generateAll(n, str) {
// 当str.length === 2 * n 说明达到上限终止 并且把str push 到res中
if (str.length === 2 * n) {
res.push(str);
return;
}
// 通过递归添加所有的可能性
generateAll(n, str + "(");
generateAll(n, str + ")");
}
// 利用堆栈来判断括号是否有效
function valid(str) {
const stack = [];
for (const s of str) {
if (s === "(") {
stack.push(s);
} else {
if (!stack.length || stack.pop() !== "(") {
return false;
}
}
}
return stack.length === 0;
}
};
/* 复杂度
时间 O(2^n)
空间 O(n)
*/
总结
今天这道题是主要是练习对递归的理解。如何用递归来生成括号,并用条件来筛选合格的括号对
大家可以看看我分享的一个专栏(前端搞算法)里面有更多关于算法的题目的分享,希望能够帮到大家,我会尽量保持每天晚上更新,如果喜欢的麻烦帮我点个赞,十分感谢
大家如果对“TS”感兴趣的可以看看我的专栏 (TypeScript常用知识),感谢大家的支持
文章内容目的在于学习讨论与分享学习算法过程中的心得体会,文中部分素材来源网络,如有侵权,请联系删除,邮箱 182450609@qq.com
\