二分查找的一些细节


title: 细说二分查找
date: 2021-01-07 19:05:39
tags:

二分查找思想

二分查找的细节问题

  • mid 取值:
    • int mid = (l+r)/2 缺陷:l+r可能超int范围
    • mid = l + (r-l)/2l==r-1时,mid = l
    • mid = l + (r-l+1)/2l==r-1时,mid = r

二分查找结题模板

精确值

```java
    /*
        find arr[i]==k and return i:

        Solution is correct must need:
            1. the arr[] is sorted
            2. the arr[] has only one answer or no answer(if arr have more than one answer,the result will be not robust) 
    */
    public int binarySearch(int[] arr, int k){  // 1. arr is sorted , 2. must has a solution??
        int l  = 0. r = arr.length - 1; 
        while(l<=r>){// when l>r exit
            int mid = l + (r-l)/2;//  
            if(arr[mid]==k){
                return mid;   //mid is answer
            }else if(arr[mid]<k){   // arr[0,mid] have no answer 
                l = mid + 1; //arr[0,mid] have no answer , so search arr[mid,]
            }else{       
                r = mid - 1;  //arr[mid,r] have no answer , so search arr[,mid]
            }
        }
        return -1;// has no answer. when the while(){} exit, we have  l>r, and arr[0,l-1] and arr[r+1,arr.length-1] has no an 
    }

```

模糊值

搜索最左侧的值

```java
    /*
        find the First Occurance of k in arr:
        
        Solution is correct must need:
            1. the arr[] is sorted
            2. the arr[] must has answer
            
    */
    public int BinarySearch(int[] arr, int k){
        int l = 0;
        int r = arr.length - 1;
        // the answer in [l,r]
        while(l<r){
            int mid = l + (r-l)/2; // mid closer to l, when l == r-1, mid == l;
            if(arr[mid]<k){  //arr[0,mid] have no answer
                l = mid + 1; //arr[0,mid] have no answer, so the answer in arr[mid+1,r]
            }else{
                r = mid; //arr[0,mid] have an answer, so the answer in arr[l,mid].  (if arr has more than 1 answer??)
            }
        }
        // if(arr[l]!=k) return -1;  //if allow arr has no answer , we need check if the arr[l] == k. 
        
        return l; //when while(){} exit, we have  l==r, and arr[0,l-1] has no answer, arr[r, arr.length-1] has no answer. 
        //arr[0,l-1],arr[l, arr.length-1] has no answer, so the answer is l.(when arr[] must has answer)
        
    }
```

搜索最右侧的值

```java
    /*
        find the Last Occurance of k
        Solution is correct must need:
            1. the arr[] is sorted
            2. the arr[] must has answer 
    */
    public int BinarySearch(int[] arr, int k){
        int l = 0;
        int r = arr.length - 1;
        while(l<r){
            int mid = l + (r-l)/2; // when l == r-1, mid = r
            if(arr[mid]>k){ // arr[mid,r] has no answer 
                r = mid - 1;// arr[mid,r] has no answer , so search arr[l,mid-1]
            }else{
                l = mid; //arr[mid,r] has answer, so search arr[mid,r]
            }
        }
        return l;// when the while(){} eixt, l == r
    }
```

万用型

```java  
    /*
        find the closest to k 
    */
    public int binarySearch(int arr, int k){
        int l  = 0. r = arr.length - 1;
        while(l<r-1>){// when l == r-1 exit
            int mid = l + (r-l)/2;// when l == r-2 , mid = l+1  
            if(arr[mid]<k){    //arr[,mid] are <k  check(mid)
                l = mid;
            }else{       //arr[mid] >= k  
                r = mid;  
            }
        }
        if(arr[r]<k){ // 1.arr[l] <= arr[r] <= k
            return r;
        }else if(arr[l]>k){ // 2.k <= arr[l] <= arr[r]
            return l;
        }else{
            return k - arr[l] < arr[r] - k ? l : r;//3. arr[l] <= k <= arr[r]
        }
    }
    /*
        - 1. the arr[l] <= arr[r] <= k
            - prove:
                when the while(){} exit, we have l == r-2, arr[r+1,] > k , arr[l-1] <k and the solution is in [l,r].
                consider the last loop beforre while(){} exit:
                    - if(arr[mid]<k), then while(){} exit with l = mid, so after while(){}, arr[l] < k.
                        if arr[r] < k , we know arr[r+1,] > k, so the  arr[r]  is the floor(k)  , floor(k) means smaller than k and closest to k. 
                        and arr[l] == arr[mid] < k,  so arr[r] is closest to k.

                    - if(arr[mid]>=k) , while(){} exit with r = mid,  arr[r] >= k, so will not has arr[r] < k

        - 2.  k <= arr[l] <= arr[r]
            - prove: 
                when the while(){} exit, we have l == r-2, arr[r+1,] > k , arr[l-1] <k and the solution is in [l,r].
                consider the last loop beforre while(){} exit:
                    if((arr[mid]>=k), then while(){} exit with r = mid, l = l. 
                        we know ,arr[l-1] < k, if(arr[l]>k) ,arr[l] is the ceil(k). 
                        and arr[r] >= k, so arr[l] closest to k.  
        
        - 2.  arr[l] <= k <= arr[r]

    */
```
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值