二分查找|详细讲解|两种写法

二分查找

目录

  • 1 介绍
  • 2 例题引入
  • 3 “左闭右闭”写法
  • 4 “左闭右开”写法

1 介绍

二分查找适用于从一个递增或递减的有序数列中查找某一个

因此,使用二分查找的条件是:

  1. 用于查找的内容从逻辑上来看是有序的
  2. 查找的数量只能是一个而不是多个

在二分查找中,目标元素的查找区间的定义十分重要,不同的区间的定义写法不一样

二分查找通常有两种写法:

  1. 左闭右闭[left,right]
  2. 左闭右开[left,right)

2 例题引入

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。 https://leetcode.cn/problems/binary-search/description/

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


整个数组是有序的、递增的

  1. 选择数组中间的数组和需要查找的目标值比较
  2. 如果相等,直接返回下标
  3. 如果不相等
    1. 如果中间的值大于目标值,则中间数字及其右边的所有数字都大于目标值, 全部排除
    2. 如果中间的值小于目标值,则中间数字及其左边的所有数字都小于目标值, 全部排除
      二分查找|详细讲解|两种写法_第1张图片

当数组长度是奇数的时候,中间的数字的左右两边的数字的个数是一样的;当数组长度是偶数的时候,中间的数字的左右两边的数字的个数是不一样的。

不影响怎么排除的问题,无非是多排除一个数字或者少排除一个数字

  • 真正影响的是中间那个数字到底该不该加入下一次的查找中,也就是边界问题

3 “左闭右闭”写法

注意:

  • while循环中left和right的关系,是left≤right还是left
  • 迭代过程中middle和right的关系,是right=middle-1还是right=middle
int serch(int[] nums,int target){
  int size=sizeof(nums)/sizeof(int);//数组长度
  int left=0;
  int right=size-1;//定义了target在左闭右闭的区间内
  while(left<=right){
    int middle=left+(right-left)/2;
    if(nums[middle]>target){
      right=middle-1;
    }else if(nums[middle]<target){
      left=middle+1;
    }else{
      return middle;
    }
  }
  return -1;
  
}

4 “左闭右开”写法

每次查找的区间在 [left, right)

int serch(int[] nums,int target){
  int size=sizeof(nums)/sizeof(int);//数组长度
  int left=0;
  int right=size;//左闭右开,不包含right指向的那个位置
  while(left<right){
    int middle=left+(right-left)/2;
    if(nums[middle]>target){
      right=middle;//左闭右开
    }else if(nums[middle]<target){
      left=middle+1;
    }else{
      return middle;
    }
  }
  return -1;
  
}

你可能感兴趣的:(leetcode,数据结构,算法,二分查找)