携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情
括号生成
数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
来源:力扣(LeetCode) 链接:leetcode.cn/problems/ge…
分析
- n是要生成括号的对数,那有2n个符号,所以
从排列的角度递归
- 通过全排列,就可以得出所有的组合,然后再判断当前的组合是否是有效的,也就是符和括号出现顺序,这样解有些暴力,时间复杂度O(2^2n * n)
- 在生成全排列的时候,可以比较容易的得出递推公式
f(n)=f(n-1)+'('或者')',所以比较容易想到使用递归的写法来生成 - 在生成了所有的排列之后再判断是否有效,有点亡羊补牢的意思,在算法相关的题目中,未雨绸缪永远比亡羊补牢快,因此我们可以在对序列进行的排序的时候,不像全排列那样无脑排下一个,而是判断下一个是左括号还是有括号,以左括号为主,如果右括号数量小于左括号数量就放一个右括号,这样就有效的降低了时间复杂度
代码
const generateParenthesis = (n) => {
const res = [];
const go = (l, r, s) => {
if (s.length === 2 * n) {
res.push(s);
return;
}
if (l < n) go(l + 1, r, s + '(');
if (r < l) go(l, r + 1, s + ')');
};
go(0, 0, '');
return res;
};
从生成的括号长度的角度递归
- 一定是左括号开始的
- 左括号的个数一定等于右括号,并且在计算下一个位置是左括号还是右括号的时候,左括号个数都应该大于或等于右括号
代码
const generateParenthesis = (n) => {
const res = [];
const go = (l, r, s) => {
if (l > r) return;
if (l === 0 && r === 0) {
res.push(s);
return;
}
if (l > 0) go(l - 1, r, s + '(');
if (r > 0) go(l, r - 1, s + ')');
};
go(n, n, '');
return res;
};
总结
- 这道题是难度为中等的题目,当在使用递归的时候,更多想到的可能是第一种方法,在关注元素的同时也要多关注元素的另一个属性:位置。就像xy轴,在关注x轴的同时也要想一下y轴,有时候可能思路就会打开了
- 今天也是有收获的一天