热搜:fiddler git ip ios 代理
历史搜索

01. 解密前端算法题:二分查找

游客2024-11-25 12:03:01

01. 解密前端算法题:二分查找 1

题目

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

示例 1:

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

示例 2:

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

解题思路

  • left,right 两个指针分别指向当前搜索的起点和终点索引。
  • 不需要记住下面这个let mid = start + ((end - start) >> 1);之所以不用let mid = (start - end)/2,只是因为>>移位运算比除法操作性能好很多,另外就是考虑到大数溢出的情况。
  • 二分搜索只要理解搜索区间就够了,以下面的代码举例,搜索区间就是前闭后闭而不是前闭后开,如果是前闭后开,那end的初始值是nums.length
  • 我们想下为什么下面的代码是while (start <= end),结束循环的是不是start刚好大于end,具体举例来说搜索区间最后结束的时候是[3,2],没有任何一个数是既大于 3 又小于 2 的。
  • 为什么end = mid - 1start = mid + 1而不是不需要 +1,举例来说初始的搜索区间是[0,5], mid=2,假设这时候mid索引对应的值不等于要找的数,那我们下次要的搜索区间就是[0,1]和[3,5],因为mid已经对比过了,新的搜索区间要排除mid

代码:

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number}
 */
var search = function (nums, target) {
  if (nums == null || !nums.length) {
    return -1;
  }
  let left = 0,
      right = nums.length - 1;
  // 左闭右闭  结束的时候是[3,2]才有可能是空集
  while (left <= right) {
    let mid = left + ((right - left) >> 1);
    if(nums[mid] < target){ // 右区间找,left 重新赋值。区间范围[mid+1,right]
       left = mid + 1 ;
    }else if(nums[mid] > target){ //左区间找,right,重新赋值,区间范围 [left ,mid-1]
       right = mid - 1;
    }else{
        return mid
    }
  }
  return -1;
};

力扣原题连接:点击这里

标签:二分查找