ts算法题解(第35天)----leetcode 704. 二分查找

393 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

前言

每天一道算法题,手撕算法

今天可能有的朋友注意到了,我们的题目变了,变成ts,不是js,其中的原因也很简单,主要是我ts比较菜,所以为了成为一个ts菜鸟,坚持使用ts做题,要不连成为ts菜鸟的资格都没有🤣

今天我们来学习二分查找,其实二分查找并不难,但是主要是细节方面,还有就是我们如何才能把二分查找真正的记住呢?这也是我们今天要探索的

题目

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

示例 1:

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

题解

思考

对于查找类的题目来说,使用二分查找时间复杂度无疑是最快的O(logn)

我们先来上二分查找的模板,模板在手,天下我有

function binarySearch(nums:number[],target:number):number{
  let left:number = 0;
   // 这里如果-1,那么while条件中就会有等于,没有-1,那就没有等于
  let right:number = nums.length-1;
   // while是循环中花费时间最好的方法,不容反驳
  while(left<=right){
  // 这里是关键中的关键,也就是二分的核心,就是找一个中间数,这个取中间数的操作一定要记住,记住他,那么你就记住了这个模板的80%
    let mid:number = left+Math.floor((right-left)/2);
    if(nums[mid] === target){
      return mid;
      // 因为mid已经搜索过,应该从搜索区间中去除**。
    }else if(nums[mid] < target){
      left = mid + 1;
    }else if(nums[mid] > target){
      right = mid - 1;
    }
  }
  return -1;
}

我们的模版定义的right为target.length-1; while(left<=right)

可能有的同学会问为什么不取target.length;while(left<right),因为他会漏掉一个数,比如left和right都为2的时候他就会报错,这样子就会漏掉2没有参与比较,所以我们不用这个

题解

function search(nums: number[], target: number): number {
    let left:number =0;
   
    let right:number = nums.length-1;

    while(left<=right){
        let mid:number = left+Math.floor((right-left)/2);
        if(target===nums[mid]){
            return mid;
        }else if(target<nums[mid]){
            right = mid - 1;
        }else if(target>nums[mid]){
            left = left+1;
        }
    }
    return -1;
};

总结

二分查找写完了,怎么样,感觉还是很简单的吧!但是我们如何记住呢,总不能每天都来复习一遍吧。这里我们引用labuladong大师的二分搜索升天词,来进行记忆

搜索一个元素时,搜索区间两端闭。
while条件带等号,否则需要打补丁。
if相等就返回,其他的事甭操心。
mid必须加减一,因为区间两端闭。
while结束就凉凉,凄凄惨惨返-1。

这诗句真是朗朗上口,方便记忆,再次感谢labuladong大师

参考