貪心演算法思想
在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,演算法得到的是在某種意義上的區域性最優解 。
特徵
1、貪心選擇性質
一個問題的整體最優解可透過一系列區域性的最優解的選擇達到,並且每次的選擇可以依賴以前作出的選擇,但不依賴於後面要作出的選擇。這就是貪心選擇性質。對於一個具體問題,要確定它是否具有貪心選擇性質,必須證明每一步所作的貪心選擇最終導致問題的整體最優解 。
2、最優子結構性質
當一個問題的最優解包含其子問題的最優解時,稱此問題具有最優子結構性質。問題的最優子結構性質是該問題可用貪心法求解的關鍵所在。在實際應用中,至於什麼問題具有什麼樣的貪心選擇性質是不確定的,需要具體問題具體分析 。
存在問題
貪心演算法也存在如下問題:
- 不能保證解是最佳的。因為貪心演算法總是從區域性出發,並沒從整體考慮
- 貪心演算法一般用來解決求最大或最小解
- 貪心演算法只能確定某些問題的可行性範圍
用例
LeetCode - 1642 可以到達的最遠建築
給你一個整數陣列 heights ,表示建築物的高度。另有一些磚塊 bricks 和梯子 ladders 。
你從建築物 0 開始旅程,不斷向後面的建築物移動,期間可能會用到磚塊或梯子。
當從建築物 i 移動到建築物 i+1(下標 從 0 開始 )時:
如果當前建築物的高度 大於或等於 下一建築物的高度,則不需要梯子或磚塊
如果當前建築的高度 小於 下一個建築的高度,您可以使用 一架梯子 或 (h[i+1] - h[i]) 個磚塊
如果以最佳方式使用給定的梯子和磚塊,返回你可以到達的最遠建築物的下標(下標 從 0 開始 )。
利用貪心演算法
因為梯子可以跨越任意高度,所以優先使用磚塊,磚塊不夠了再使用梯子。
class Solution {
public int furthestBuilding(int[] heights, int bricks, int ladders) {
int i = 0;
while (i < heights.length - 1) {
if (heights[i] >= heights[i + 1]) {
i++;
continue;
}
int sp = heights[i + 1] - heights[i];
if (bricks >= sp) {
bricks -= sp;
i++;
continue;
}
if (ladders > 0) {
ladders--;
i++;
continue;
}
break;
}
return i;
}
}
只做到區域性最優解,對於本道題,用例如
[2,7,8,9,10,11]
5
1
不能透過,因為2-7差值最大,原理上應該使用梯子就可以,後面差值小的才使用磚塊。
進一步最佳化
loading....