今天進行了阿里巴巴的面試,整體面試感受還行,不出意外,我會進入到二面階段。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