前言
- 常网IT源码上线啦!
- 本篇录入吊打面试官专栏,希望能祝君拿下Offer一臂之力,各位看官感兴趣可移步🚶。
- 有人说面试造火箭,进去拧螺丝;其实个人觉得问的问题是项目中涉及的点 || 热门的技术栈都是很好的面试体验,不要是旁门左道冷门的知识,实际上并不会用到的。
- 接下来想分享一些自己在项目中遇到的技术选型以及问题场景。
辛苦了一年,咱也不是身无分纹还有抬头纹鱼尾纹法令纹。

一、前言
现在还是金三银四,去找虐,很多大厂都喜欢让候选人手写算法题,她也不例外。
其实给的题不难,但是要看你怎么优雅的写出如诗一般的代码。
那么,请看题目。
输入一个字符串,打印出该字符串中,所有字符的排列组合。
哦,看着还行啊。
二、分析
盲猜递归。
要打印出字符串中所有字符的排列组合,可以使用递归的方法。
于是,如诗一般的代码就写出来了。
java
function permute(str, memo = [], result = []) {
// 如果memo的长度等于str的长度,说明找到了一个完整的排列,将其添加到结果数组中
if (memo.length === str.length) {
result.push(memo.join(''));
return;
}
// 遍历字符串中的每个字符
for (let i = 0; i < str.length; i++) {
// 如果当前字符已经在memo中,则跳过以避免重复
if (memo.includes(str[i])) continue;
// 将当前字符添加到memo中,并递归调用permute函数继续处理剩余字符
memo.push(str[i]);
console.log(memo, 'meno', i)
permute(str, memo, result);
// 回溯,将当前字符从memo中移除,以便尝试其他排列
memo.pop();
console.log(memo, 'pop', i)
}
return result;
}
// 示例用法
const inputString = "abc";
const permutations = permute(inputString);
// 打印所有排列组合
permutations.forEach(permutation => {
console.log(permutation);
// abc
// VM84:30 acb
// VM84:30 bac
// VM84:30 bca
// VM84:30 cab
// VM84:30 cba
});
代码看着有点少,但接下来我的分析,想要细点。
我们好好来分析,要了解好递归思想。
首先,我们执行permute方法,进行for循环
此时i = 0;memo为空。
push第一个,a
接着进入递归permute(str, memo = [a], result);
-
我们调用,来到for循环,此时memo = [a]
-
接着momo开始push个b,memo = [a, b]
-
进入递归permute(str, memo = [a, b], result);
-
调用,来到for循环,此时memo = [a, b]
-
接着momo开始push个c,memo = [a, b, c]
- 进入递归permute(str, memo = [a, b, c], result); 走进if,result添加第一个完整的数组
-
后面还有个memo.pop(); 此时的memo = [a, b, c]
-
-
他后面还有个memo.pop(); 此时的memo = [a, b]
-
-
接着momo开始push个c,memo = [a, c]
-
进入递归permute(str, memo = [a, c], result);
-
调用,来到for循环,此时memo = [a, c]
-
接着momo开始push个b,memo = [a, c, b]
- 进入递归permute(str, memo = [a, c, b], result); 走进if,result添加第2个完整的数组
-
后面还有个memo.pop(); 此时的memo = [a, c, b]
-
-
他后面还有个memo.pop(); 此时的memo = [a, c]
-
别忘记了后面memo.pop(); 此时的memo = [a]

这是给大家详细的演示i = 0的情况。
接着后面还有i = 1和i = 2的情况,就不带大家走了,相信看完i = 0就懂了,多看几遍。
另外i = 1,b的情况;i = 2,c的情况,打印也列出来了,大家看看自己做的时候,对下答案。

三、递归
他们说:想要自己真的懂,就要讲给别人也懂,这个过程,你会更通透这个知识点。
刚好最近考软考,也有一些算法思想在里面。
递归算法通过分治思想 将问题分解为子问题:固定一个字符,递归排列剩余字符。当剩余字符排列完成时,与已固定的字符组合形成完整排列。
递归三要素:
-
终止条件:当前排列长度等于原字符串长度,存入结果集。
-
子问题拆分:每次选择一个未被使用的字符加入当前排列。
-
回溯机制:递归完成后撤销当前选择,尝试其他可能性
空间复杂度O(n),递归调用栈深度为n。
至此撒花~
后记
递归虽好,但要小心使用。
很多初学者,用了之后,可能会进入死循环,递归终止的边界,防止无限调用。
还记得刚开始学递归的时候,是斐波那契数列中,F(n) = F(n-1) + F(n-2)
,这玩意会被重复计算,如fib(3)。
未优化的递归时间复杂度为指数级,恐怖如斯。
优化的点可以有:
缓存中间结果,避免重复计算。
尾递归优化。
还有快排、阶乘
如果想要最优解,才是最难的。
如果看得不是很明白,可以多看几遍,一通则通,接下来的算法题像是打通这道门。
我们在实际项目中或多或少遇到一些奇奇怪怪的问题。
自己也会对一些写法的思考,为什么不行🤔,又为什么行了?
最后,祝君能拿下满意的offer。
我是Dignity_呱,来交个朋友呀,有朋自远方来,不亦乐乎呀!深夜末班车
👍 如果对您有帮助,您的点赞是我前进的润滑剂。
以往推荐
前端哪有什么设计模式(12k+)
为什么没人用mixin(7k+)