面试题:如何在JavaScript中不使用length方法与循环查找数组中间元素
如何在JavaScript中不使用length方法和循环查找数组的中间元素
你的问题很有意思——既要避开length属性,又不能用循环语句,确实需要换个思路。先说说你现有代码的问题,再给你一个符合要求的解决方案。
你的代码为什么得到4而不是3?
先拆解你这段代码的问题:
var arr =[1,2,3,4,5]; function middleElement(arr){ var i=0, j=i+2; while(arr[j] !=null){ i++; j=i+2; } return arr[i] } middleElement(arr);
这里有两个核心问题:
- 违反了“不使用循环”的要求:代码里用了
while循环,不符合题目限制; - 逻辑判断偏差:当
j=4时,arr[j]是5(存在),所以会进入循环让i变成3、j变成5。此时arr[j]是undefined,而在JavaScript中undefined == null为true,所以arr[j] != null是false,循环停止,返回arr[3]也就是4。但正确的逻辑应该是:当快指针无法再跳两步时,慢指针就停在中间,而不是等快指针走到最后一个元素时再移动慢指针。
符合要求的解决方案:递归实现快慢指针
既然不能用循环,我们可以用递归来模拟快慢指针的逻辑:快指针每次“跳两步”,慢指针每次“跳一步”,当快指针无法再跳两步时,慢指针的位置就是数组的中间元素。这个方法既不用length属性,也不用任何循环语句。
代码实现:
const arr = [1, 2, 3, 4, 5]; function findMiddle(arr, slow = 0, fast = 0) { // 当快指针无法再跳两步时,返回慢指针指向的元素 if (!arr[fast + 1] || !arr[fast + 2]) { return arr[slow]; } // 递归调用:慢指针走1步,快指针走2步 return findMiddle(arr, slow + 1, fast + 2); } console.log(findMiddle(arr)); // 输出3,符合预期
逻辑解释:
- 初始时,慢指针和快指针都从索引0开始;
- 每次递归,慢指针前进1位,快指针前进2位;
- 当快指针的下一个位置(
fast+1)或下下个位置(fast+2)不存在时,说明快指针已经走到数组末尾附近,此时慢指针正好指向奇数长度数组的中间元素; - 对于偶数长度数组(比如
[1,2,3,4]),这个方法会返回左中间元素(2),如果需要右中间元素(3),可以把判断条件调整为if (!arr[fast + 2]),此时返回arr[slow + 1]即可。
补充说明:为什么这个方法符合要求?
- 没有使用
Array.prototype.length:完全通过访问数组元素的存在性来判断边界; - 没有使用循环语句:用递归代替了循环的迭代逻辑,递归不属于JavaScript中的循环语句(for/while/do-while)范畴。
内容的提问来源于stack exchange,提问作者user944513
相关产品推荐
相关产品推荐

