JS千面之数组的二分查找

今天进行了阿里巴巴的面试,整体面试感受还行,不出意外,我会进入到二面阶段。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

相关文章
相关标签/搜索