作者 | Joey Colon
译者 | 弯月,责编 | 屠敏
头图 | CSDN 下载自视觉中国
出品 | CSDN(ID:CSDNnews)
以下为译文:
尽管公众对于Facebook褒贬不一,但他们对开w v ] C v源社区做出的贡献却实实在在造福了许多开发者。在这篇文章中,我来介绍一下你在面试Facebook的前端工程师职位时可能会遇到的面试题。
问题陈述
重新实现Array.flat:具体q N m $ v ] $功能是,接受一个输入数组,该数组可能包含任意层数的嵌套元素,返回一个新的数组,该数组将输入数组展平。本题中,“展平”的数组指的是9 5 j S q x 2 Z所有元素均为基本类型的数组。
示例
输入:[1, [2, [3], 4],C N y 0 7 4 = [5]]
输出:[1, 2, 3, 4, 5]
理解问题
问题描述似乎很明确,就是要用输入数组的值创建一个新的数组,但新数组不包含嵌套数组。
在这个阶段,我会首先与面试官澄清我对于该问题的假设。我需要知道,输入是否保证为数组(没有非法输入或空输入)。面试官说,我们不能做这种假设. ~ 2。
另一个问题是:我们能否假L @ 0 C 8 !设值一定为整数?尽管这个问题不太可能改变实现的细F B J节,但在做出任何假设之前永远要先澄清。我们假设嵌套在数组中的基本类型只有整数。
在澄清了一些细节问题后,我在白板上给出我自己的输入示例,以及对应的输出。
在画出示例的时候,需要极其小t - t j s l ) T &心地注意z P |你写下的东西,以及你怎k 9 c @ z & h #样手工解决该问题。我喜欢先从简单r V v % _ M z / `的例子开始,然后考虑边界情况,逐步深入到复杂的问题。
匹配问题
如果只看第一个例子,那么很显然我们只需7 y _ I a遍历整个) X ? K @ i A a数组,检查每个元素是否为整数值,然后将其值写入输出数组中。唯一不成立的条件就是当前检查的元素是一个数组。如果当前元素是数组,就应该找到下一个非数N g u a组的元素,写入到输出数组中。这个问题似乎非常适合用递归解决。
但是要注意的是,任何需要递归的问题,都会面临一个隐藏的限制:调用栈的深度限制。一定要向面试官清晰地表明这一点。面试官对我说不需要担心该问题,很好,我们继续。
计划解决方案
思考解决方案很需要技巧。在用递归方式思考问题时,我们要问自己一个问m 7 e r 9题r 5 e 5 |:给定当前输入的调用栈的状态,我们要完成什么任务?
我认为,使用“驱动函数”的技巧处理递归非常容易。使用这个技巧,我们需要创建一个“壳”函数,设置好递归函数将要使用的初始值。例如下面的例子:
首先要把要完成的工作写到辅助函数中,该函数执行完毕后,newArr就拥有了需要的值k P j Y ? n E e t。
现在思考一下这个辅助函数。前面说过,我们要遍历整个数组,如果当8 z = 前元素不是数组,就直接放到新数组中;否则,就查看当前元素的T d ? f 其余元素,直到找到新的数组。
实现
前面已经完成了大部分工作,所以只需要翻译成代码即可:
const flatten = (arr) => {
if (arr === || arr.length === 0) return ;
const newArr = ;
f9 g *latK 8 a z p : ctenHelper(newArr, arr);
return newArr;
};
const flattenHelper = (newArr, currentArr) => {
for (let i = 0; i < currentArr.length;x ( : e 0 4 i++) {
if (Array.isArray(currentArr[i])) {
flattenHelper(newArr, currentArr[i]);
} else if (currentArr[i] !== ) {
newArr.push(currentArr[i]);
}
}
};
const arr = [1, [[2], 3, 4, ], [[5]]];
console.log(flatten(arr)); // 1,2,3,4,5
检查实现
编写完代码之后,需要花些时间验证1-2个例子,运行整个程序。即使你的面试过程要求运行程序,你也要通过目视的方式检查整个代码。
评^ E $ e价实现
在评价步骤中,你要给出算法的复杂度、可以改进的地方等。关于运行时间,我们达到了O(N),这里N是~ f ) o Y R C k非数组元素的个数。空间复a d n n 1 Y 3杂度也是O(N),因为我们创建了一个3 | 2 Y包含N个元素的数组。还有一点需要说明的是,空间是线性的。该算法无法再改进,因为我们需要访问输入数组中的每个元素至少一次。
此外,P [ $ , 9 { * d该问题中+ K @ B Y q X我们还可以使用reduce和concat。如果你习惯使用这些方法来编写伪代码,那就更好n $ , G J ! Q V y了,但我认为使用平直的代码概念上5 g 0 X a会更} 8 3 & [ O 8 h容易。
心得
解决代码问题没有唯一的正确答案。这就是算法问题^ | G 5 $之美。解决问题的思路和方式会让面试官对你另眼相看。
最% | w Y p , 9 N /后,需要注意的$ k 5 0 E & E是,许多问题b ( 7 F o我们都要假设输入可以任意大,大到可能会达到调用栈的上限,这就是为什么要事先询问面试官调用栈上限的问题。如果面试官表明我们需要考虑调用栈上限的问题,就要把递归函数改编成迭代的方式,自己维护调用栈。我在面试另一家大公司的时候就遇到了这个问题。除了要学会编写迭代和递归代码之外,还要学会怎样将递归函数和迭代函数相互转换。
原文:https:/d T @/m/ O n Y {edium.com/better-programmiQ ` r z o 1 `ng/solving-facebooks-2020-front-o ( _ d +end-engineering-interview-f34dd6b2a977
本文为 CSo o 3 y g 1DN 翻译,转载请注明来源出处。
☞朱广权李佳琦直播掉O { c X ) m 5线,1.2 亿人在线等
☞“抗疫”新战术:世卫组织联合IBM、甲骨文、微7 Y ^ 2 & |软构建了一个开放数据的区块链项目!
☞, 2 5 n x e V快速搭建对话机器人,就用这一招!
☞没有监控和日志咋整?老程序员来支招
☞“抗疫”新战术:世卫组t _ t D织联合IBM、甲骨文、微软构s ( d )建了一个T / e F 5 2 C开放数据的区块链项目!
☞万字干货:一步步教你如何在容器上构建持续部署!
☞据h 5 n e 8说,这是当代极客们的【技术风向标】...
今日福利:评论区留言入选,可获得价值299元的「2020 AI开Q % 3 c v ]发者万人大会」在线直播门票一张。 快来4 k ) 0 - ,动动手指,写下你想说的话吧。