二分查找的简单分享

155 阅读1分钟

二分查找

  1. 使用条件:(1)有序 (2)无重复数据

  2. 具体理论:具体理论就是,会设置两个指针,分别为left和right,left指向数组的首位,right指向最后一个位置 ,或者最后一个位置的后一位(这里就区分出是左闭右闭区间还是左闭右开区间),然后查找某一个数值时,由left和right得出一个中间值mid,判断该mid是否为所求的值,如果是则返回索引或者做其他操作,如果大于目标值,则让right变为mid-1(左闭右闭),再次求mid;如果小于目标值,则将left变为mid+1,直到查找完整个数据或者找到目标数据。

  3. 两中区间定义:

    (1)左闭右闭区间,是指left为首地址的值,right为末尾地址的值,即[left,right],二分查找的实质就是根据条件更新这个边界,比如中间值大了,那就调整right,那么right怎么调整呢,如果right = mid,则更新区间为[left,mid],显然mid还要再做一个边界判断,不合理,所以right应该为mid-1,左边界同理,不做过多解释,代码如下:

    
    class Solution {
       public int search(int[] nums, int target) {
           //左闭右闭
           int left = 0;
           int right = nums.length-1;
           if(nums.length == 0){
               return -1;
           }else{
               while(left<=right){
                   int middle = (left+right)/2;
                   if(target > nums[middle]){
                       left = middle + 1;
                   }else if(target < nums[middle]){
                       right = middle - 1;
                   }else{
                       return middle;
                   }
               }
           }
           return -1;
    
       }
    }
    

    (2)左闭右开区间同理,就是一个换区间的问题,开始区间为[left,right),在搜索一次后,显然不包含right,所以循环终止条件right不能等于left,假设目标值大于mid,则要调整边界值,如果调整边界值为mid-1,则区间范围为[left,mid-1),则不包含mid-1,就会出问题,所以调整为[left,mid)。代码如下:

    class Solution {
       public int search(int[] nums, int target) {
           //左闭右闭
           int left = 0;
           int right = nums.length;
           if(nums.length == 0){
               return -1;
           }else{
               while(left<right){
                   int middle = (left+right)/2;
                   if(target > nums[middle]){
                       left = middle+1;
                   }else if(target < nums[middle]){
                       right = middle;
                   }else{
                       return middle;
                   }
               }
           }
           return -1;
    
       }
    }