免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
如何理解二分查找?生活中還能用來設計騙局?

腳本之家

你與百萬開發(fā)者在一起

來源公眾號:苦逼的碼農(nóng)

作者:帥地

期末考要來了,最近小秋正在從零開始復習算法相關知識….

一道簡單的算法題

帥地:聽說你最近正在臨時飽佛教復習各種算法?

小秋:對啊,算法太難了,把我頭都搞大了,不過,感覺自己復習的好像還不錯。

帥地:那我找一道簡單的題考考你?

小秋:好啊,好啊,正好可以試試水。

帥地:給你一個有序數(shù)組,例如

然后我給出一個元素 target,你返回它對應數(shù)組的下標,如果數(shù)組中不存在這個元素的話,則返回 -1。例如

1、我給出 target = 18,則你需要返回 5。

2、我給出 target = 1,你需要返回 0。

3、我給出 target = 10,由于數(shù)組中不存在 10 這個元素,所以你需要返回 -1。

小秋:這也太簡單了吧,我從左到右遍歷數(shù)組所有元素,就可以找出來了。

帥地:這是一種方法,不過你這種方法的時間復雜度為 O(n),有沒有時間復雜度上更小的方法呢?

小秋:那我可以采用哈希表來存儲,把數(shù)組元素作為 key,對應的下標作為 value,這樣的話,以后需要查找某個元素了,我就可以在時間復雜度為 O(1) 找到對應的元素下標了。

帥地:你這種方法,需要用哈希表來存放元素,雖然時間復雜度為 O(1),但是空間復雜度為 O(n) 了,你能不能在時間復雜度和空間復雜度折中一下,找出更加優(yōu)美的方法呢?

小秋:好像,,目前沒啥思路。

神速的二分查找

帥地:你聽說過二分查找嗎?

小秋:二分查找?什么鬼?

帥地:這道題就可以用二分查找來解決了,我來給你講講吧。

小秋:好啊,好啊。

帥地:其實呢,對于這道題,由于數(shù)組是有序的,我們每次在查找的時候,可以直接從中間元素開始比較,例如我們要查找 target = 10,這個元素,我們把 target 與數(shù)組中間的那個元素 15,進行比較。

(1)如果 target 比 15 小,那么 15 以及 15 右邊的所有元素一定比 target 大,所以 target 只能存在于 15 的左邊元素中。

(2)如果 target 比 15 大,那么 15 以及 15 左邊的所有元素一定比 target 小,所以 target 只能存在于 15 的右邊元素中。

(3)如果 target 與 15 相等,則直接把 15 對應的下標返回即可。

在這個例子中,target = 10 比 15 小,所以 target 只可能存在于 15 的左邊元素中

接下來我們只需要在左半部分查找這個元素就可以了,右半部分的元素可以不用管了,你看,通過這種方式,只需要一次比較,我們就可以把查找的范圍縮小了一半。

接著我們繼續(xù)把 target 與中間元素比較,這時候中間元素是 5,15比 5 大,所以 target 只可能存在于 5 右邊的元素中

接下來我們繼續(xù)查找,這時中間元素是 10,和 target 相等,所以直接把 10 的下標 index = 2 返回。

二分查找的本質(zhì)

帥地:小秋啊,這種每次都從中間元素開始比較,并且一次比較后就能把查找范圍縮小一半的方法,就叫做二分查找了,這種二分查找的時間復雜度是 O(logn),空間復雜度是 O(1),可以說非??斓牧?。

小秋:那什么情況下可以使用二分查找這種方法呢?

帥地:要使用二分查找,給的數(shù)據(jù)需要具備兩個基本的特性

(1)給的數(shù)據(jù)是有序的。

(2)給的數(shù)據(jù)支持隨機訪問

小秋:什么是隨機訪問呢?

帥地:例如像數(shù)組就支持隨機訪問了,例如你要訪問第 5 個元素,那么你就可以用下標為 4,即 arr[4] 來快速訪問第五個元素了。而鏈表就不支持隨機訪問了,例如你要訪問鏈表的第 5 個元素,你無法像數(shù)組那樣,直接用下標來定位,只能從鏈表頭部一個一個遍歷到第五個。

小秋:哦,我知道了,只有支持隨機訪問,我們才能根據(jù)數(shù)組最左邊和最右邊的下標,直接定位到數(shù)組的中間元素。

帥地:是的,那你可以根據(jù)剛才那道題寫一下代碼嗎?

小秋:沒問題。

    public static int binarySearch(int target, int[] arr) {
        // 數(shù)組最左邊元素下標
        int left = 0;
        // 數(shù)組最右邊元素下標
        int right = arr.length - 1;
        while (left <= right) {
            // 中間元素下標
            int mid = (right + left) / 2;
            if (arr[mid] > target) {
                right = mid - 1;
            } else if (arr[mid] < target) {
                left = mid + 1;
            } else {
                return arr[mid];
            }
        }
        return -1;
    }

90% 的人都會犯的錯誤

帥地:你寫的基本正確,不過有個小問題,就是算中間元素下標那里

mid = (left + right) / 2;

你這種方法有時候會產(chǎn)生溢出的哦。例如,我們知道 int 整數(shù)的最大值大概是 2^31 - 1 大概為 21 億。而 left 和 right 這兩個數(shù)相加是有可能超過 21 億的,例如 left = 12億,right = 13 億。這個時候,兩個數(shù)的和超過了最大值,就會產(chǎn)生溢出了。

小秋:那該怎么寫?

帥地:正確的寫法應該是這樣的

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

這樣,就能保存不會出現(xiàn)溢出的情況了。

二分查找在生活中的騙局

帥地:其實在我們的生活中,二分查找也是有挺多應用的,例如用二分查找來做壞事。

小秋:壞事?可以給我舉例看看嗎?

帥地:有時候臨近一些比賽了,例如全世界性的足球大賽,有時候我們會收到一些郵件,有人謊稱他會神預算,例如今天是德國和法國比賽,他會跟你說一定是德國勝,然后跟另外一部分人今天一定是法國勝。

而德國和法國,總有一個人會勝,那么他可以跟 10000人說德國勝,10000人說法國勝。我們假如是德國勝了,那么在 10000 人看來它的預算是正確的。

接著德國和俄羅斯比賽,它會在那 10000 人中,跟 5000人說德國勝,5000人說俄羅斯勝。那么在 5000 看來它的預算還是正確的….

就這樣,每次它都從被他預算正確的那一部分人繼續(xù)吹他會神預算,那么在有些人看來,他果真連續(xù)預算正確,這個時候,這些人可能就會認為,他真的有神預算的能力,于是,可能就會相信它說的話了,進而就會被他所欺騙。

小秋:雖然我沒收到這類郵件,但是我經(jīng)常收到一些六合彩的短信

帥地:是的,這些,就是利用的二分查找的思想了。

二分查找?沒有你想的那么簡單

帥地:小秋啊,剛才給你講的那道題,可以說是最簡單的了,其實,對于二分查找,有很多變形題的,往往不會那么簡單。

小秋:那你可以給我出幾道,看我能不能現(xiàn)學現(xiàn)賣。

帥地:那我給你兩道題吧。

1、實現(xiàn) pow(x, n)函數(shù):即計算 x 的 n 次方。不準使用我之前給你講的位運算【算法技巧】位運算裝逼指南。

2、搜索選擇排序數(shù)組:假設按照升序排序的數(shù)組在預先未知的某個點上進行了旋轉。( 例如,數(shù)組 [0,1,2,4,5,6,7] 可能變?yōu)?[4,5,6,7,0,1,2] )。

搜索一個給定的目標值,如果數(shù)組中存在這個目標值,則返回它的索引,否則返回 -1 。你可以假設數(shù)組中不存在重復的元素。你的算法時間復雜度必須是 O(log n) 級別。

示例 1:

輸入: nums = [4,5,6,7,0,1,2], target = 0
輸出: 4
示例 2:

輸入: nums = [4,5,6,7,0,1,2], target = 3
輸出: -1

這兩道題,可以說是中等難度的變形題了,跟我說說怎么做?

小秋:這….,我才剛學完,能不能給我點時間讓讓想想?

帥地:大概多長呢?

小秋:不長,兩天時間就可以了。

帥地:兩天 還不長…… 好吧,那兩天后見。

總結

這次主要講解了二分查找的基本思想以及生活在的例子,二分查找思想雖然不難,不過卻有很多不容易的題,后面的問題,如果小秋沒做出來,我就下次給大家講解。如果小秋做出來的,我們就來聽聽他怎么做的,敬請期待。

本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
《劍指offer-第二版》-面試題03-數(shù)組中重復的數(shù)字-01-找出數(shù)組中重復的數(shù)字(Java)
各種排序算法總結
C#數(shù)據(jù)結構與算法揭秘六
圖解堆排序,帶你徹底了解清楚!
這或許是東半球分析十大排序算法最好的一篇文章
拜托,別再問我什么是堆了!
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服