题目

给定一个 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;
};

力扣原题连接:点击这里

「点点赞赏,手留余香」

2

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:
1. 本站所有文章教程及资源素材均来源于网络与用户分享或为本站原创,仅限用于学习和研究。
2. 如果内容损害你的权益请联系客服QQ:1642748312给予处理。
码云笔记 » 01. 二分查找

发表评论

IT互联网行业相关广告投放 更专业 更精准

立即查看 联系我们