前言
众所周知,面试官总是喜欢在算法题和编程题上刨根问底,听到还能优化吗?还有其他解法吗?兄弟们头都是大的,可没办法啊,只能硬着头皮上了,不然答对了也不算满分。今天给大家分享两道面试官喜欢问的两道题。
1. 求x的n次方
听到这道题,我心里想着:“这也太简单了,没难度啊。”
function fun1(x,n){
let result = 1;
for(let i = 0; i<n; i++) {
result*=x;
}
return result;
}
于是我轻轻松松写出一个函数,通过一个循环将将 x 乘以自身 n 次,最终得到结果。
结果面试官问:“还有吗?”
我心想:“就知道你还有这一手,我特意留了个递归的方法没说。”
function fun1(x,n){
// 退出条件
if(n === 0) {
return 1;
}else {
return x * fun1(x, n - 1);
}
}
于是我又轻轻松松的写出来了,通过递归不断调用自身,得出结果。
我心想:“这下你没话说了吧,赶快开始下一题吧。”
结果面试官又问:“你这两个方法有啥区别啊,时间复杂度都是O(n),还能优化一下吗?”
这可苦了我了,我左思右想也想不出一个好的解决办法,实在没办法了,我只能对面试官说:“不好意思,老师,我实在没有思路,能稍微提醒一下吗?”
面试官看着我叹了一口气,说:“x的n次方 等于 x的二分之n次方 乘以 自己本身。”
这一下,我豁然开朗,只要通过将 n 减半并根据 n 的奇偶性来进行不同的计算就可以得到结果了。
function fun1(x,n) {
if(n === 0) {
return 1;
}
let t = fun1(x, Math.floor(n / 2));
if(n % 2 === 1) {
return t * t * x; // 奇数 t * t * x
}else {
return t * t;// 偶数 t * t
}
}
通过这种思路一下就避免了简单递归中出现的大量重复计算,将时间复杂度优化到了O(log2 n)。
2. 类数组
“你了解类数组吗?”面试官如此问道。
我斟酌了一下语言,说道:“类数组就是那些不是 Array 对象,但是具有一些类似数组的属性和方法的对象。”
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>类数组</title>
</head>
<body>
<p>这是第1个段落</p>
<p>这是第2个段落</p>
<p>这是第3个段落</p>
<p>这是第4个段落</p>
<p>这是第5个段落</p>
<p>这是第6个段落</p>
<p>这是第7个段落</p>
<p>这是第8个段落</p>
<p>这是第9个段落</p>
<p>这是第10个段落</p>
<script>
const nodeArr = document.getElementsByTagName('p');
const nodeList = document.querySelectorAll('p');
console.log(nodeArr,nodeList);
nodeList.join(',')
</script>
</body>
</html>
“这段代码中 nodeArr 和 nodeList 有什么区别。”面试官问。
我:“它们通过 DOM 方法返回的分别是 HTMLCollection 和 NodeList ,虽然它们都是类数组,但它们的属性不同。例如......”
面试官:“不错,那请问 nodeList.join(',') 这段代码运行结果是什么”
我:“emm,因为数组和类数组的内置的方法不同,所以大概率会报错吧。”
面试官:“不错,那请问它们为什么属性和方法会不同呢,数组与类数组,类数组与类数组,它们的属性和方法是从哪来的呢。”
面对面试官的步步逼近。我有点招架不住,不知如何表达,心想:“学校没教啊!”
我突然灵机一动,在JavaScript中,管你什么数组,类数组都是对象,既然是对象那就有原型,而原型上的属性和方法是可以继承的,它们属性和方法不同的原因应该就是原型不同。
我答道:“数组和类数组的属性不同的主要原因是它们指向的原型不同,原型都不同,继承下来的属性和方法肯定也不同,类数组也是如此,尽管都叫类数组,但 HTMLCollection指向的原型是 HTMLCollection.prototype ,而 NodeList 指向的是 NodeList.prototype 。它们的原型其实也不相同。
面试官:“非常不错,那如果我想得到的这些类数组具体的属性和方法该怎么办呢?”
想通了后,这些都是简单的问题。
我:“只需在控制台输入 nodeList.__proto__ 就可以看到所有的属性和方法了。”
结语
面对面试官的死缠烂打,千万不要轻言放弃,实在不会了可以腆着脸皮问问面试官,毕竟算法题中总有一道是很难的,对于这种有难度的题,他不仅考察你的逻辑能力,代码能力,还会考察你的学习能力和社交能力。希望这篇文章能给你带来帮助,我们一起进步,顶峰相见!!