二分法其實很簡單,為什麼老是寫不對!!

2022-09-16 06:39:12 字數 2539 閱讀 5106

相信很多人對二分法是又愛又恨,愛是在於它思想簡單,效率確實高, 恨是恨在為什麼總是寫不對呢

二分查詢涉及的很多的邊界條件,邏輯比較簡單,就是寫不好

甚至有的同學乾脆把二分法背來了得了

其實背過的同學應該會有體會,硬背二分法,過一段時間依然會寫錯

例如 迴圈中到底是 小於 還是 小於等於, 到底是+1 呢,還是要-1呢

這是為什麼呢,主要是我們對區間的定義沒有想清楚,這就是我們的不變數

我們要在二分查詢的過程中,保持不變數,這也就是迴圈不變數 (感興趣的同學可以查一查)

題目是leetcode編號35的面試題. 搜尋插入位置

這道題目,我們要在陣列中插入目標值,無非是這四種情況

這四種情況確認清楚了,我們就可以嘗試解題了

暴力解法思路很直接,就是for迴圈遍歷一下,時間複雜度是o(n)

既然暴力解法的時間複雜度是on,我們就要嘗試一下使用二分查詢法。

大家注意這道題目的前提是陣列是有序陣列,這也是使用二分查詢的基礎條件

以後大家只要看到面試題裡給出的陣列是有序陣列,都可以想一想是否可以使用二分法。

同時題目還強調陣列中無重複元素,因為一旦有重複元素,使用二分查詢法返回的元素下表可能不是唯一的。

下圖來闡述一下二分法的大體思路,例如在這個陣列中,我們使用二分法尋找元素為5的位置,並返回其下標,如下圖

開始左邊界為0,右邊界下表為7,那麼中間位置下表是3, arr[3] > 5

左區間為我們下一步的查詢範圍,

左邊界為0,右邊界為2,中間位置下表為1 arr[1] < 5

右區間為我們下一步的查詢範圍

左邊界2,右邊界2,a[2] == 5,

返回下表2。

接下來呢我們來看一下二分法具體實現

我們定義 target 是在乙個在左閉右閉的區間裡,也就是[left, right]

這就決定了我們 這個二分法的**如何去寫,大家看如下**

class solution  else if (nums[middle] < target)  else 

}// 分別處理如下四種情況

// 目標值在陣列所有元素之前,此時區間為[0, -1],所以return right + 1

// 目標值等於陣列中某乙個元素 return middle;

// 目標值插入陣列中的位置,一定是我們查詢的範圍 [left, right]之後,return right + 1

// 目標值在陣列所有元素之後的情況,也是我們查詢的範圍 [left, right]之後, return right + 1

return right + 1;}};

時間複雜度:o(logn)

時間複雜度:o(1)

效率如下:

如果說我們定義 target 是在乙個在左閉右開的區間裡,也就是[left, right)

那麼二分法的邊界處理方式則截然不同。

不變數是[left, right)的區間,如下**可以看出是如何在迴圈中堅持不變數的。

class solution  else if (nums[middle] < target)  else 

}// 分別處理如下四種情況

// 目標值在陣列所有元素之前,此時區間為 [0,0),所以可以return right

// 目標值等於陣列中某乙個元素 return middle

// 目標值插入陣列中的位置 [left, right) ,return right 即可

// 目標值在陣列所有元素之後的情況 [left, right),return right 即可

return right;}};

時間複雜度:o(logn)

時間複雜度:o(1)

從上面兩種二分法的**中,我們可以看到是如何處理二分查詢過程中的邊界情況

很多同學二分寫不好,就是因為邊界總是不知道 該是<= 還是< 呢,

是 right = middle - 1呢 還是 right = middle呢

這都是因為沒有意識到去區間的定義,區間的定義就是我們的不變數

在二分部查詢的過程只要遵循著區間的定義也就是這個不變數

我們就可以很輕鬆的寫出二分法

以上講解大家應該對二分法中迴圈不變數有乙個直觀的感受

理解的查詢區間的定義(不變數),然後在二分迴圈中遇到了不知該如何處理的邊界條件的時候

就去想一下 我們區間的定義,這樣就知道邊界條件應該如何去寫了

通過這次講解希望幫助大家可以徹底理解二分法!

簡單遞迴 二分法查詢

題目描述 設有n個數已經按從大到小的順序排列,現在輸入x,判斷它是否在這n個數中,如果存在則輸出 yes 否則輸出 no 題目分析 該問題屬於資料的查詢問題,資料查詢有多種方法,通常方法是 順序查詢和二分查詢,當n個數排好序時,用二分查詢方法速度大大加快。二分查詢演算法 1 設有n個數,存放在a陣列...

二分法的簡單拓展

高中數學也好,初中數學也好,老師都講過二分法,這類題目多多少少也做過。比如計算根號2的值等等。計算根號2的值 近似的 思想還是二分法 計算根號2的近似值 const double eps 1e 5 doublef double x double calsort return left int mai...

leetcode162為什麼能用二分法求解

這道題。我第一遍沒做出來。參看了一些題解後,感覺它們大部分都沒講明白這道題為什麼可以用二分法。所以這裡就把我的思考分享出來吧。首先,我們需要注意題目的三個條件 1 限定了nums i nums i 1 這為我們排除了出現連續相等子串行的情況。2 num 1 和num n 的值為負無窮,那麼陣列在左邊...