C 演算法集錦(14) 貪心演算法

2021-10-20 10:11:32 字數 2113 閱讀 7952

跳躍遊戲 ii

貪心演算法可以理解為一種特殊的動態規劃為題,擁有一些更加特殊的性質,可以進一步降低動態規劃演算法的時間複雜度。

來看幾道題目熟悉一下這種「不斷尋求區域性最優」的演算法。

輸入乙個非負整數陣列nums,陣列元素nums[i]表示的是:如果你站在位置 i ,最多能夠往前跳幾步。

現在你站在第乙個位置nums[0],試問你能否跳到陣列的最後乙個位置?

例:[1,2,3,4,5],可以

[1,2,0,0,4],不行

這題相對比較簡單一些吧,當然不要去用回溯,用回溯的話時間複雜度太高。

成功的方式太多了,但是失敗的方式只有乙個:有足夠多的0橫亙在其中,導致不論怎麼努力就是跳不過去。

我們哪幾個栗子來試一下吧:

[

0,····]

//點點點的意思是隨便你填什麼數字都無所謂了[1

,2,1

,0,···][2

,0,0

,···]

//還有啥特例嗎?

我們來分析一下上面的栗子(我們假設陣列有-1格,nums[-1] = 1,我們從nums[-1]開始):

第乙個栗子:在下標為0的時候遇到了絕望的0,從下標為-1的地方為此前能前進的最大步數1,無法跨越,終結。

第二個栗子:在下標為3的時候遇到了絕望的0,從下標為1的地方獲得了此前能前進的最大步數2,無法跨越,失敗。

第三個栗子:在下標為2的時候遇到了絕望的0,從下標為0的地方獲得了此前能前進的最大步數2,無法跨越,失敗。

這三個栗子中,我們能提取出什麼有效的資訊?

0

-(-1) =13

-1=2

2-0=

2

對吧。

還有呢?為什麼不變通一下,比如說例2中,不通過下標為2的點去中轉呢?因為中轉也無效啊。

那就是說我們要去嘗試著中轉。

這樣講可能會有點繞啊,我把例2改一下:[1,2,2,0],這不就活了嗎!

拿兩個例2來比對一下:

(以flag紀錄當前能夠到達的最遠距離)

[1,

2,1,

0,···]

//下標0最多到下標1,flag = 1;下標1最多到下標3,flag = 3;下標2最多到下標3,flag = 3;下標3,flag = 3;卒[1

,2,2

,0]//下標0:flag = 1;下標1:flag = 3;下標2:flag = 4

可以看到,當flag == 下標 的時候,就涼涼了。

所以,我們寫出**:

bool

canjump

(vector<

int>

& nums)

return farthest >= n-1;

}

跟上面差不多,但是這次保證你能跳到最後,問你最少跳幾次。

看著好眼熟啊,好像前面寫過一道這樣的題。換硬幣是吧。

去遞迴選取後續跳法裡面的最優,屬於一種:從後向前的解法,可以理解為從底層開始層序遍歷一棵樹。只不過我們後來通過備忘錄對這棵樹進行了剪枝,不然真的不忍直視啊。

貪心演算法是什麼?貪心演算法會選擇當下最有潛力的一步。

舉個例子:[2,3,1,2,5,1]

當你現在在下標0的位置,你可以跳兩步。動歸的話會遞迴去算這兩步到最終結果的最優步數,但是貪心演算法不這樣。

貪心演算法是每次盡可能多跳嗎?nonono,選擇當下最有潛力的:在座標1的位置,你有三個選擇;在座標2的位置,你只有乙個選擇,所以貪心演算法會讓你選擇跳到座標1。這就是貪心演算法的區域性最優(不要奇思妙想啥反例,要用貪心演算法,就要承擔它的失誤率)。

接下來,我們來寫**:

貪心演算法 C

貪心演算法 又稱貪婪演算法 是指,在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,他所做出的是在某種意義上的區域性最優解。貪心演算法並不保證會得到最優解,但是在某些問題上貪心演算法的解就是最優解。要會判斷乙個問題能否用貪心演算法來計算。第乙個問題 找零 假設商店老闆...

演算法 貪心演算法

把乙個複雜問題分解為一系列較為簡單的區域性最優選擇,每乙個選擇都是對當前解的乙個擴充套件,知道獲得問題的完整解。在解決問題的策略上目光短淺,只根據當前已有的資訊做出選擇,而且一旦做出了選擇,不管將來有什麼結果這個選擇都不會改變。換言之,貪心法並不是從整體最優考慮,它所做出的選擇只是在某種意義上的區域...

演算法 貪心演算法

集合覆蓋問題 旅行商問題等都屬於np完全問題,在數學領域上並沒有快速得到最優解的方案,非常適合用貪婪演算法。判斷方法 1.元素較少時,一般執行速度很快,但隨著元素數量增多,速度會變得非常慢 2.涉及到需要計算比較 所有的組合 情況的通常是np完全問題 3.無法分割成小問題,必須考慮各種可能的情況。這...