算法解题有感
记录一下自己第一次在做算法题的时候把解题的思路用注释写出来,一步步推导,然后套用相应的算法实现,并且一次提交成功!!!
回看自己的解题思路,好像看到了Deepseek深度思考的影子,在此,向每天被自己叨扰的Deepseek致敬!!!
LeetCode
22. 括号生成:数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的
括号组合。
示例 1:
输入:n = 3
输出:[“((()))”,“(()())”,“(())()”,“()(())”,“()()()”]
示例 2:
输入:n = 1
输出:[“()”]
/**
* @param {number} n
* @return {string[]}
*/
var generateParenthesis = function (n) {
// 思考n和n-1有什么区别,n的话多一对括号,这对括号是否可以放在任意位置,但是要满足有效。
// 有效的括号组合指的是左括号和右括号使用栈增减最后刚好等于0的。
// 既然这样的话,只要通过不同方式的进栈出栈,就能找出不同的组合。
// 以n=2举例,方式一进(,出),进(,出)。方式二进(,进(,出),出),这样就得到了2种方式。
// 这样的话问题就转换成了进出方式的组合。n对括号的话必然会进n次,出n次,而且过程中进的次数>=出的次数
// 想一下回溯算法,回溯算法可以用来枚举出所有可能性,回溯算法主要是尝试和回退。这里尝试有两种选择,一是进(,二是出),有点类似于二叉树左子树和右子树,可以用path记录当前括号组合,是进还是出用计数器,当进(的时候,计数器+1,当进)的时候计数器-1。
// 剪枝的条件是,计数器<0了,不符合有效括号
// 记录解的条件是,计数器===0,且path长度===2n
function loop(type = '(', count = 0, path = [], res = []) {
// 剪枝
if (count < 0) {
// 不符合有效括号组合
return;
}
if (path.length === 2 * n) {
// 到达最底端了
return;
}
// 尝试
path.push(type);
if (type === '(') {
count++;
} else {
count--;
}
// 记录解
if (count === 0 && path.length === 2 * n) {
res.push(path.join(''));
}
loop('(', count, path, res);
loop(')', count, path, res);
// 回退
path.pop();
}
const res = [];
loop('(', 0, [], res)
return res;
};