chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

二分查找算法如何運(yùn)用?

算法與數(shù)據(jù)結(jié)構(gòu) ? 來源:labuladong ? 作者:labuladong ? 2020-10-30 09:39 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

讀完本文,你可以去力扣解決:410.分割數(shù)組的最大值(Hard)

經(jīng)常有讀者問我,讀了之前的爆文二分查找框架詳解之后,二分查找的算法他寫的很溜了,但僅僅局限于在數(shù)組中搜索元素,不知道底怎么在算法題里面運(yùn)用二分查找技巧來優(yōu)化效率。

那我先說結(jié)論,你想用二分查找技巧優(yōu)化算法,首先要把 for 循環(huán)形式的暴力算法寫出來,如果算法中存在如下形式的 for 循環(huán):

//func(i)是i的單調(diào)函數(shù)(遞增遞減都可以) intfunc(inti); //形如這種for循環(huán)可以用二分查找技巧優(yōu)化效率 for(inti=0;i

如果func(i)函數(shù)是在i上單調(diào)的函數(shù),一定可以使用二分查找技巧優(yōu)化 for 循環(huán)。

「在i上單調(diào)的函數(shù)」是指func(i)的返回值隨著i的增加而增加,或者隨著i的增加而減小。

為什么滿足這個條件就可以使用二分查找?因為這個邏輯和「在有序數(shù)組中查找一個元素」是完全一樣的呀!

在有序數(shù)組nums中查找某一個數(shù)target,是不是最簡單二分查找形式?我們看下普通的 for 循環(huán)遍歷算法:

//nums是一個有序數(shù)組 int[]nums; //target是要搜索的元素 inttarget; //搜索target在nums中的索引 for(inti=0;i

既然nums是有序數(shù)組,你把nums[i]看做函數(shù)調(diào)用,是不是可以理解為nums在參數(shù)i上是單調(diào)的?這是不是和之前說的func(i)函數(shù)完全一樣?

當(dāng)然,前文二分查找框架詳解說過,二分查找算法還有搜索左側(cè)、右側(cè)邊界的變體,怎么運(yùn)用到具體算法問題中呢?

還是注意觀察 for 循環(huán)形式,只是不一定是func(i) == target作為終止條件,可能是<=或者>=的關(guān)系,這個可以根據(jù)具體的題目意思來推斷,我們實操一下力扣第 410 題「分割數(shù)組的最大值」,難度Hard:

函數(shù)簽名如下:

intsplitArray(int[]nums,intm);

這個題目有點類似前文一道經(jīng)典動態(tài)規(guī)劃題目高樓扔雞蛋,題目比較繞,又是最大值又是最小值的。

簡單說,給你輸入一個數(shù)組nums和數(shù)字m,你要把nums分割成m個子數(shù)組。

肯定有不止一種分割方法,每種分割方法都會把nums分成m個子數(shù)組,這m個子數(shù)組中肯定有一個和最大的子數(shù)組對吧。

我們想要找一個分割方法,該方法分割出的最大子數(shù)組和是所有方法中最大子數(shù)組和最小的。

請你的算法返回這個分割方法對應(yīng)的最大子數(shù)組和。

我滴媽呀,這個題目看了就覺得 Hard,完全沒思路,這題怎么能和二分查找算法扯上關(guān)系?

說個小插曲,快手面試有一道畫師畫畫的算法題,很難,就是以這道題為原型。當(dāng)時我沒做過這道力扣題,面試有點懵,不過之前文章二分查找算法運(yùn)用寫了兩道類似的比較簡單的題目,外加面試官的提示,把那道題做出來了。

面試做算法題的時候,題目一般都會要求算法的時間復(fù)雜度,如果你發(fā)現(xiàn) O(NlogN) 這樣存在對數(shù)的復(fù)雜度,一般都要往二分查找的方向上靠,這也算是個小套路。

言歸正傳,如何解決這道數(shù)組分割的問題?

首先,一個拍腦袋的思路就是用回溯算法框架暴力窮舉唄,我簡單說下思路:

你不是要我把nums分割成m個子數(shù)組,然后計算巴拉巴拉又是最大又是最小的那個最值嗎?那我把所有分割方案都窮舉出來,那個最值肯定可以算出來對吧?

怎么窮舉呢?把nums分割成m個子數(shù)組,相當(dāng)于在len(nums)個元素的序列中切m - 1刀,對于每兩個元素之間的間隙,我們都有兩種「選擇」,切一刀,或者不切。

你看,這不就是標(biāo)準(zhǔn)的回溯暴力窮舉思路嘛,我們根據(jù)窮舉結(jié)果去計算每種方案的最大子數(shù)組和,肯定可以算出答案。

但是回溯的缺點就是復(fù)雜度很高,我們剛才說的思路其實就是「組合」嘛,時間復(fù)雜度就是組合公式:

時間復(fù)雜度其實是非常高的,所以回溯算法不是一個好的思路,還是得上二分查找技巧,反向思考這道題。

現(xiàn)在題目是固定了m的值,讓我們確定一個最大子數(shù)組和;所謂反向思考就是說,我們可以反過來,限制一個最大子數(shù)組和max,來反推最大子數(shù)組和為max時,至少可以將nums分割成幾個子數(shù)組。

比如說我們可以寫這樣一個split函數(shù):

//在每個子數(shù)組和不超過max的條件下, //計算nums至少可以分割成幾個子數(shù)組 intsplit(int[]nums,intmax);

比如說nums = [7,2,5,10],若限制max = 10,則split函數(shù)返回 3,即nums數(shù)組最少能分割成三個子數(shù)組,分別是[7,2],[5],[10]。

如果我們找到一個最小max值,滿足split(nums, max)和m相等,那么這個max值不就是符合題意的「最小的最大子數(shù)組和」嗎?

現(xiàn)在就簡單了,我們只要對max進(jìn)行窮舉就行,那么最大子數(shù)組和max的取值范圍是什么呢?

顯然,子數(shù)組至少包含一個元素,至多包含整個數(shù)組,所以「最大」子數(shù)組和的取值范圍就是閉區(qū)間[max(nums), sum(nums)],也就是最大元素值到整個數(shù)組和之間。

那么,我們就可以寫出如下代碼:

/*主函數(shù),計算最大子數(shù)組和*/ intsplitArray(int[]nums,intm){ intlo=getMax(nums),hi=getSum(nums); for(intmax=lo;max<=?hi;?max++)?{ ????????//?如果最大子數(shù)組和是?max, ????????//?至少可以把?nums?分割成?n?個子數(shù)組 ????????int?n?=?split(nums,?max); ????????//?為什么是?<=?不是?==?? ????????if?(n?<=?m)?{ ????????????return?max; ????????} ????} ????return?-1; } /*?輔助函數(shù),若限制最大子數(shù)組和為?max, 計算?nums?至少可以被分割成幾個子數(shù)組?*/ int?split(int[]?nums,?int?max)?{ ????//?至少可以分割的子數(shù)組數(shù)量 ????int?count?=?1; ????//?記錄每個子數(shù)組的元素和 ????int?sum?=?0; ????for?(int?i?=?0;?i?max){ //如果當(dāng)前子數(shù)組和大于max限制 //則這個子數(shù)組不能再添加元素了 count++; sum=nums[i]; }else{ //當(dāng)前子數(shù)組和還沒達(dá)到max限制 //還可以添加元素 sum+=nums[i]; } } returncount; } //計算數(shù)組中的最大值 intgetMax(int[]nums){ intres=0; for(intn:nums) res=Math.max(n,res); returnres; } //計算數(shù)組元素和 intgetSum(int[]nums){ intres=0; for(intn:nums) res+=n; returnres; }

這段代碼有兩個關(guān)鍵問題:

1、對max變量的窮舉是從lo到hi即從小到大的。

這是因為我們求的是「最大子數(shù)組和」的「最小值」,且split函數(shù)的返回值有單調(diào)性,所以從小到大遍歷,第一個滿足條件的值就是「最小值」。

2、函數(shù)返回的條件是n <= m,而不是n == m。按照之前的思路,應(yīng)該n == m才對吧?

其實,split函數(shù)采用了貪心的策略,計算的是max限制下至少能夠?qū)ums分割成幾個子數(shù)組。

舉個例子,輸入nums = [2,1,1], m = 3,顯然分割方法只有一種,即每個元素都認(rèn)為是一個子數(shù)組,最大子數(shù)組和為 2。

但是,我們的算法會在區(qū)間[2,4]窮舉max,當(dāng)max = 2時,split會算出nums至少可以被分割成n = 2個子數(shù)組[2]和[1,1]。

當(dāng)max = 3時算出n = 2,當(dāng)max = 4時算出n = 1,顯然都是小于m = 3的。

所以我們不能用n == m而必須用n <= m來找到答案,因為如果你能把nums分割成 2 個子數(shù)組([2],[1,1]),那么肯定也可以分割成 3 個子數(shù)組([2],[1],[1])。

好了,現(xiàn)在 for 循環(huán)的暴力算法已經(jīng)寫完了,但是無法通過力扣的判題系統(tǒng),會超時。

由于split是單調(diào)函數(shù),且符合二分查找技巧進(jìn)行優(yōu)化的標(biāo)志,所以可以試圖改造成二分查找。

那么應(yīng)該使用搜索左側(cè)邊界的二分查找,還是搜索右側(cè)邊界的二分查找呢?這個還是要看我們的算法邏輯:

intlo=getMax(nums),hi=getSum(nums); for(intmax=lo;max<=?hi;?max++)?{ ????int?n?=?split(nums,?max); ????if?(n?<=?m)?{ ????????return?max; ????} }

可能存在多個max使得split(nums, max)算出相同的n,因為我們的算法會返回最小的那個max,所以應(yīng)該使用搜索左側(cè)邊界的二分查找算法。

現(xiàn)在,問題變?yōu)椋涸陂]區(qū)間[lo, hi]中搜索一個最小的max,使得split(nums, max)恰好等于m。

那么,我們就可以直接套用搜索左側(cè)邊界的二分搜索框架改寫代碼:

intsplitArray(int[]nums,intm){ //一般搜索區(qū)間是左開右閉的,所以hi要額外加一 intlo=getMax(nums),hi=getSum(nums)+1; while(lom){ //最大子數(shù)組和上限低了,增加一些 lo=mid+1; } } returnlo; } intsplit(int[]nums,intmax){/*見上文*/} intgetMax(int[]nums){/*見上文*/} intgetSum(int[]nums){/*見上文*/}

這段二分搜索的代碼就是標(biāo)準(zhǔn)的搜索左側(cè)邊界的代碼框架,如果不理解可以參見前文二分查找框架詳解,這里就不展開了。

至此,這道題就通過二分查找技巧高效解決了。假設(shè)nums元素個數(shù)為N,元素和為S,則split函數(shù)的復(fù)雜度為O(N),二分查找的復(fù)雜度為O(logS),所以算法的總時間復(fù)雜度為O(N*logS)

責(zé)任編輯:lq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 算法
    +關(guān)注

    關(guān)注

    23

    文章

    4784

    瀏覽量

    98105
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4417

    瀏覽量

    67568
  • 數(shù)組
    +關(guān)注

    關(guān)注

    1

    文章

    420

    瀏覽量

    27378

原文標(biāo)題:二分查找算法如何運(yùn)用?我和快手面試官進(jìn)行了深入探討…

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    單片機(jī)常用的14個C語言算法分享

    ]中,待查找的關(guān)鍵值為key,把key與a數(shù)組中的元素從頭到尾一一進(jìn)行比較查找,若相同,查找成功,若找不到,則查找失敗。(查找子過程如下。i
    發(fā)表于 01-29 06:59

    進(jìn)制查找(Binary Search)介紹

    進(jìn)制查找(Binary Search)用于在已排序的數(shù)組中執(zhí)行進(jìn)制查找的函數(shù)。 int binary_search(int arr[], int size, int targ
    發(fā)表于 12-12 06:54

    線性搜索與二分搜索介紹

    線性搜索(Linear Search):從數(shù)組的第一個元素開始,依次將當(dāng)前元素與目標(biāo)值進(jìn)行比較,直到找到目標(biāo)值或搜索完整個數(shù)組。 二分搜索(Binary Search):在有序數(shù)組中查找某一特定元素
    發(fā)表于 12-01 07:36

    C語言的常見算法

    ) { return i; } } return -1; } ``` ### 二分查找 (Binary Search) ```c int binarySearch(int arr[], int l
    發(fā)表于 11-24 08:29

    詳解SOA的增益譜仿真

    本文利用簡化的載流子速率方程,以及二分法迭代,仿真得到了外部注入(電流及輸入光功率)與增益的關(guān)系。
    的頭像 發(fā)表于 11-08 09:58 ?783次閱讀
    詳解SOA的增益譜仿真

    SM4算法實現(xiàn)分享(一)算法原理

    SM4組加密算法采用的是非線性迭代結(jié)構(gòu),以字為單位進(jìn)行加密、解密運(yùn)算,每次迭代稱為一輪變換,每輪變換包括S盒變換、非線性變換、線性變換、合成變換。加解密算法與密鑰擴(kuò)展都是采用32輪非線性迭代結(jié)構(gòu)
    發(fā)表于 10-30 08:10

    AES加解密算法邏輯實現(xiàn)及其在蜂鳥E203SoC上的應(yīng)用介紹

    算法中唯一的非線性模塊,通常有兩種實現(xiàn)方式:查找表法和復(fù)合域降階法。查找表法的實現(xiàn)較為簡單,由于S盒的實質(zhì)是一一映射,在verilog中直接使用case語句即可;而復(fù)合域降階法需要根據(jù)字節(jié)代換的數(shù)學(xué)公式
    發(fā)表于 10-29 07:29

    查找表與多項式近似算法實現(xiàn)初等函數(shù)

    查找表與多項式近似結(jié)合算法是一種把查找算法和多項式近似算法綜合到一起的算法。這種
    發(fā)表于 10-28 08:10

    AES和SM4算法的可重構(gòu)分析

    一、AES和SM4算法特點分析 基于前面幾篇分享,我們對AES和SM4的算法流程有了較為清晰的認(rèn)識,接下來對AES和SM4算法的共同點進(jìn)行分析,得出者的可重構(gòu)設(shè)計思路。 首先,這里
    發(fā)表于 10-23 07:26

    分享一個嵌入式學(xué)習(xí)階段規(guī)劃

    (如指針實現(xiàn)鏈表增刪查改),排查內(nèi)存泄漏、野指針數(shù)據(jù)結(jié)構(gòu)與算法:掌握線性表 / 棧 / 樹等結(jié)構(gòu),學(xué)查找 / 排序算法,手寫代碼(如二分查找
    發(fā)表于 09-12 15:11

    機(jī)載高光譜系統(tǒng)與機(jī)器學(xué)習(xí)算法結(jié)合實踐丨雙利合譜機(jī)載高光譜相機(jī)在小麥監(jiān)測應(yīng)用

    板校正、大氣校正和 NDVI 計算來增強(qiáng)植被與背景的區(qū)分度。在 FVC 提取方面,對比了像素二分法、DPK-means 算法和支持向量機(jī)(SVM)分類,最終,研究通過誤差分析(EF、RMSE)、擬合度(R2)和誤差分布圖評估不同方法的表現(xiàn),驗證 DPK-means
    的頭像 發(fā)表于 07-24 16:36 ?764次閱讀
    機(jī)載高光譜系統(tǒng)與機(jī)器學(xué)習(xí)<b class='flag-5'>算法</b>結(jié)合實踐丨雙利合譜機(jī)載高光譜相機(jī)在小麥監(jiān)測應(yīng)用

    用一杯咖啡的時間,讀懂AI二分類如何守護(hù)工業(yè)質(zhì)量

    您是否想過,工廠里那些"非黑即白"的判斷,正由AI用最簡潔的邏輯守護(hù)質(zhì)量?今天,讓我們通過一個零件組裝中的彈墊錯裝、漏裝、多裝、錯序分類案例,拆解AI二分類技術(shù)的核心
    的頭像 發(fā)表于 07-08 07:35 ?840次閱讀
    用一杯咖啡的時間,讀懂AI<b class='flag-5'>二分</b>類如何守護(hù)工業(yè)質(zhì)量

    請問對SPDIF_Rx傳來的48K,24Bit立體聲信號作約160階FIR電子二分頻濾波器需怎樣的MCU性能?

    請問對SPDIF_Rx 傳來的48K,24Bit立體聲信號作約160階FIR電子二分頻濾波器需怎樣的MCU性能?
    發(fā)表于 04-29 07:00

    請問對SPDIF_Rx 傳來的48K,24Bit立體聲信號作約160階FIR電子二分頻濾波器需怎樣的MCU性能?

    請問對SPDIF_Rx 傳來的48K,24Bit立體聲信號作約160階FIR電子二分頻濾波器需怎樣的MCU性能?
    發(fā)表于 04-24 06:33

    請問對SPDIF_Rx傳來的48K,24Bit立體聲信號作約160階FIR電子二分頻濾波器需怎樣的MCU性能?

    請問對SPDIF_Rx 傳來的48K,24Bit立體聲信號作約160階FIR電子二分頻濾波器需怎樣的MCU性能?
    發(fā)表于 04-22 07:42