今天进行了阿里巴巴的面试,整体面试感受还行,不出意外,我会进入到二面阶段。javascript
在面试过程当中,面试官(槿凉)问了一个问题:我有一个算法问题,在一个有序数组中,如何查找已知的值的索引位置?java
问题:有序数组中,如何查找已知的值的索引位置?
当听到这个题目的时候,个人脑海中闪过Array.slice()?Array.find()?不会的,不会这么简单的,再看“有序数组”、“已知值”、“索引”等字眼,我就知道原来考察的是js的二分算法,也叫折半算法。面试
举个例子:算法
// 定义有效数组 const Arr = [2,4,5,6,7,8,9]; // 方法调用 findIndex(Arr, 2) // 返回0 findIndex(Arr, 9) // 返回6 findIndex(Arr, 5) // 返回2 findIndex(Arr, 1) // 返回undefined findIndex(Arr, 10) // 返回undefined
注意:二分查找(折半查找)只能在有序数组下进行,无序数组不能使用,如const Arr = [10,3,5,2,1,9],须要将无序数组进行升序排列后才能进行查找。
原理:用上面的例子,好比查找7的索引值,现将数组折半,let center = Math.floor(Arr.length -1 / 2),而后分别在[0, center]和[center, Arr.length - 1]范围中查找,若是7在[center, Arr.length - 1]范围中,继续递归将[center, Arr.length - 1]范围折半进行查找,周而复始,直到最后一个值,就是咱们所须要的索引值。数组
实现findIndex方法
有了大白话的原理,接下来实现findIndex的方法就变得很容易了。spa
/* * @params [Array] arr 有序的目标数组 * @params [Number] num 已知的值 * */ function findIndex(arr, num) { // 数组长度 let length = arr.length; // 初始化左边范围的索引 let left = 0; // 初始化右边范围的索引 let right = length - 1; // 折半中间值索引 let center = Math.floor((left + right) / 2); // 循环查找 while(left <= length - 1 && right >= 0){ if (arr[center] === num) return center; if (left === right) return "您查找的数不存在"; if (arr[center] > num) { right = center-1; center = Math.floor((left + right) / 2); }else if (arr[center] < num) { left = center + 1; center= Math.floor((left + right) / 2); } } }
如今想一想,还不如一个循环遍从来的方便,囧~
*************************************************************************************************************
吃完饭想一想,二分查找也不是一无可取,在大规模的查找问题下,用折半遍历的时间换取内存空间的解决,也还能够啊~,至少节省内存消耗嘛!
接下来我会专门开一个专题,去将这段时间的大厂面试题作一些讲解。code
*************************************************************************************************************递归
若是你看完这篇文章以为有帮助,请点赞加收藏哦,只看不点赞等于耍流氓~索引
*************************************************************************************************************ip