手把手帶你學演算法 本週小結!(貪心演算法系列三)

2021-10-12 08:35:20 字數 2518 閱讀 7412

本文 已經收錄,裡面還有leetcode刷題攻略、各個型別經典題目刷題順序、思維導圖,可以fork到自己倉庫,有空看一看一定會有所收穫,如果對你有幫助也給乙個star支援一下吧!

本週開始恢復了題目系列。

對於貪心,大多數同學都會感覺,不就是常識嘛,這算啥演算法,那麼本週的題目就可以帶大家初步領略一下貪心的巧妙,貪心演算法往往妙的出其不意。

在貪心演算法:加油站中給出每乙個加油站的汽油和開到這個加油站的消耗,問汽車能不能開一圈。

這道題目咋眼一看,感覺是一道模擬題,模擬一下汽車從每乙個節點出發看看能不能開一圈,時間複雜度是o(n^2)。

即使用模擬這種情況,也挺考察**技巧的。

for迴圈適合模擬從頭到尾的遍歷,而while迴圈適合模擬環形遍歷,對於本題的場景要善於使用while!

如果**功力不到位,就模擬這種情況,可能寫的也會很費勁。

本題的貪心解法,我給出兩種解法。

對於解法一,其實我並不認為這是貪心,因為沒有找出區域性最優,而是直接從全域性最優的角度上思考問題,但思路很巧妙,值得學習一下。

對於解法二,貪心的區域性最優:當前累加rest[j]的和cursum一旦小於0,起始位置至少要是j+1,因為從j開始一定不行。全域性最優:找到可以跑一圈的起始位置。

這裡是可以從區域性最優推出全域性最優的,想不出反例,那就試試貪心。

解法二就體現出貪心的精髓,同時大家也會發現,雖然貪心是常識,有些常識並不容易,甚至很難!

在貪心演算法:分發糖果中我們第一次接觸了需要考慮兩個維度的情況。

例如這道題,是先考慮左邊呢,還是考慮右邊呢?

先考慮哪一邊都可以! 就別兩邊一起考慮,那樣就把自己陷進去了

如圖:

接著在貪心另一邊,左孩子大於右孩子,左孩子的糖果就要比右孩子多。

此時candyvec[i](第i個小孩的糖果數量,左孩子)就有兩個選擇了,乙個是candyvec[i + 1] + 1(從右孩子這個加1得到的糖果數量),乙個是candyvec[i](之前比較右孩子大於左孩子得到的糖果數量)。

那麼第二次貪心的區域性最優:取candyvec[i + 1] + 1 和 candyvec[i] 最大的糖果數量,保證第i個小孩的糖果數量即大於左邊的也大於右邊的。全域性最優:相鄰的孩子中,評分高的孩子獲得更多的糖果。

區域性最優可以推出全域性最優。

如圖:

在貪心演算法:檸檬水找零中我們模擬了買檸檬水找零的過程。

這道題目剛一看,可能會有點懵,這要怎麼找零才能保證完整全部賬單的找零呢?

但仔細一琢磨就會發現,可供我們做判斷的空間非常少!

美元10只能給賬單20找零,而美元5可以給賬單10和賬單20找零,美元5更萬能!

區域性最優:遇到賬單20,優先消耗美元10,完成本次找零。全域性最優:完成全部賬單的找零。

區域性最優可以推出全域性最優。

所以把能遇到的情況分析一下,只要分析到具體情況了,一下子就豁然開朗了。

這道題目其實是一道簡單題,但如果一開始就想從整體上尋找找零方案,就會把自己陷進去,各種情況一交叉,只會越想越複雜了。

在貪心演算法:根據身高重建佇列中,我們再一次遇到了需要考慮兩個維度的情況。

之前我們已經做過一道類似的了就是貪心演算法:分發糖果,但本題比分發糖果難不少!

貪心演算法:根據身高重建佇列中依然是要確定一邊,然後在考慮另一邊,兩邊一起考慮一定會蒙圈。

那麼本題先確定k還是先確定h呢,也就是究竟先按h排序呢,還先按照k排序呢?

這裡其實很考察大家的思考過程,如果按照k來從小到大排序,排完之後,會發現k的排列並不符合條件,身高也不符合條件,兩個維度哪乙個都沒確定下來。

所以先從大到小按照h排個序,再來貪心k

此時區域性最優:優先按身高高的people的k來插入。插入操作過後的people滿足佇列屬性。全域性最優:最後都做完插入操作,整個佇列滿足題目佇列屬性。

區域性最優可以推出全域性最優,找不出反例,那麼就來貪心。

「**隨想錄」裡已經講了十一道貪心題目了,大家可以發現在每一道題目的講解中,我都是把什麼是區域性最優,和什麼是全域性最優說清楚。

雖然有時候感覺貪心就是常識,但如果真正是常識性的題目,其實是模擬題,就不是貪心演算法了!例如貪心演算法:加油站中的貪心方法一,其實我就認為不是貪心演算法,而是直接從全域性最優的角度上來模擬,因為方法裡沒有體現區域性最優的過程。

而且大家也會發現,貪心並沒有想象中的那麼簡單,貪心往往妙的出其不意,觸不及防!哈哈

下週依然還是貪心,敬請期待!

循序漸進學演算法,認準「**隨想錄」,carl手把手帶你過關斬將!

總結 貪心演算法 本週小結!(貪心演算法系列四)

在貪心演算法 用最少數量的箭引爆氣球中,我們開始講解了重疊區間問題,用最少的弓箭射爆所有氣球,其本質就是找到最大的重疊區間。按照左邊界經行排序後,如果氣球重疊了,重疊氣球中右邊邊界的最小值 之前的區間一定需要乙個弓箭 如圖 模擬射氣球的過程,很多同學真的要去模擬了,實時把氣球從陣列中移走,這麼寫的話...

學習筆記(5 手把手帶你學Python 案例講解

立即學習 把1 100中的奇數裝入列表 l for i in range 1,101 if i 2 0 print l 把2 100中的質數加到列表中 l for i in range 2,101 flag true 按所有數都是質數來說 for j in range 2,i 開始驗證 if i j...

leetcode 本週小結!(貪心演算法系列四)

本文 已經收錄,裡面還有leetcode刷題攻略 各個型別經典題目刷題順序 思維導圖,可以fork到自己倉庫,有空看一看一定會有所收穫,如果對你有幫助也給乙個star支援一下吧!在貪心演算法 用最少數量的箭引爆氣球中,我們開始講解了重疊區間問題,用最少的弓箭射爆所有氣球,其本質就是找到最大的重疊區間...