704.二分查找

48 阅读1分钟

题目:

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

输入: nums = [-1,0,3,5,9,12], target = 2
输出: -1
解释: 2 不存在 nums 中因此返回 -1

// js的现有api
// console.log(nums.indexOf(target));

// 自写遍历
function findMe(list, target) {
  if (list?.length < 1) {
    return -1;
  }
  let indexMe = undefined;
  let start = new Date().getTime();
  console.log("起:", start);
  list.forEach((ele, index) => {
    if (ele === target) {
      indexMe = index;
    }
  });
  let end = new Date().getTime();
  console.log("止:", end);
  console.log("差:", end - start);

  return indexMe !== undefined ? indexMe : -1;
}

console.log(findMe(nums, target));

// 二分查找法:左闭右闭
function onBinary(nums, target) {
  let left = 0;
  let right = nums.length - 1;

  let start = new Date().getTime();
  console.log("起:", start);

  while (left <= right) {
    let middle = Math.floor((left + right) / 2);
    if (nums[middle] > target) {
      right = middle - 1;
    } else if (nums[middle] < target) {
      left = middle + 1;
    } else {
      let end = new Date().getTime();
      console.log("止1:", end);
      console.log("差1:", end - start);
      return middle;
    }
  }
  let end = new Date().getTime();
  console.log("止1:", end);
  console.log("差1:", end - start);
  return -1;
}

console.log(onBinary(nums, target));

// 二分查找法:左闭右开
function onBinary2(nums, target) {
  let middle,
    left = 0,
    right = nums.length;
  // middle = left + ((right - left) >> 1);
  // console.log("位运算", middle, left + (right - left) / 2);

  while (left < right) {
    // 位运算,防止大数溢出
    middle = left + ((right - left) >> 1);
    if (nums[middle] > target) {
      right = middle;
    } else if (nums[middle] < target) {
      left = middle + 1;
    } else {
      return middle;
    }
  }

  return -1;
}
onBinary2(nums, target);

通过扩大数据量,可以看出,二分查找优化 相对于 普通遍历,性能是相当的明显的

image.png