[數據結構與算法]關於二分查找的理解

關於二分查找的理解

leetcode_35搜索插入的位置這道題中,liweiwei大佬詳細的介紹了二分查找最關鍵的一個問題,就是如何避免陷入死循環。在此我根據大佬的筆記,總結一下自己的理解。

首先來看題目:

給定一個排序數組和一個目標值,在數組中找到目標值,並返回其索引。如果目標值不存在於數組中,返回它將會被按順序插入的位置。

你可以假設數組中無重複元素。
輸入: [1,3,5,6], 5
輸出: 2

正常的解法如下:

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        int size = nums.size();
        if (size == 0) {
            return 0;
        }
        // 特判
        if (nums[size - 1] < target) {
            return size;
        }
        int left = 0;
        int right = size - 1;
        while (left < right) {
            // int mid = left + (right - left + 1)/2;//右中位數
           int mid = left + (right-left)/2; //左中位數
            if (nums[mid] < target) {
                left = mid + 1;
            }
            else if (nums[mid] == target) {
                return mid;
            }
            else {
                right = mid;
            }
        }
        return left; 
    }
};

這道題目的重點在與 左右區間的如何劃分,這個地方如何理解呢?

正如二分法所要求的mid,當求得mid,之後,根據mid的值和目標值進行比較,會存在區間的劃分的兩種情況:

  • 情況1:

    [left,mid][mid+1,right]

  • 情況2:

    [left,mid-1][mid,right]

但是mid的值怎麼計算呢?這個地方有兩個需要注意的點!

注意點1:如何防止溢出

正常對於mid的計算我們都是:

int mid = (left+right)/2;

這種情況下,當數組很長的時候,兩個數直接相加就可能溢出。

所以一種比較好的習慣是:

int mid = left + (right-left)/2;

注意點2:mid值是上取整還是下取整?

假設我們最後剩下的搜索區間是[2,3],那麼因爲int向下取整的原因,用注意點1裏的方法,mid的值就是2;

如果是下取整,那麼會存在什麼情況呢?

我們分別代入區間劃分的兩種情況下進行測試:

  • 情況1:

    int mid = 2;
    //判斷1:此時right=mid
    [left,mid] = [2,2]
    //判斷2:left=mid+1
    [mid+1,right] = [3,3]
    

    沒什麼問題.

    return left!

  • 情況2:

    int mid = 2;
    //判斷1:此時right=mid-1
    [left,mid-1] = [2,1]
    //判斷2:left=mid
    [mid,right] = [2,3] //陷入死循環!!!
    

    在判斷1的情況下明顯出錯了!區間都劃分的不對了。或者出現 死循環!

如果我們使用的是上取整呢?

也就是這樣:

int mid = left + (right-left+1)/2;

再次分別代入以下區間劃分的情況下進行測試:

  • 情況1:

    int mid = 3;
    //判斷1:此時right=mid
    [left,mid] = [2,3]//陷入死循環!!!
    //判斷2:left=mid+1
    [mid+1,right] = [4,3]//區間不對了!!!
    

    出現錯誤!不是陷入死循環,就是區間判斷錯誤!不知道該如何退出!

  • 情況2:

    int mid = 3;
    //判斷1:此時right=mid-1
    [left,mid-1] = [2,2]
    //判斷2:left=mid
    [mid,right] = [3,3]
    

    這種情況下安全退出!

所以這就是大佬說的,當遇到left = mid的時候,才需要調整爲上取整!!!!

相似的練習題!

704. 二分查找

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章