學一下貪心演算法-學一下貪心演算法

小白不爱發表於2024-03-08

貪心演算法思想

在對問題求解時,總是做出在當前看來是最好的選擇。也就是說,不從整體最優上加以考慮,演算法得到的是在某種意義上的區域性最優解 。

特徵

1、貪心選擇性質

  一個問題的整體最優解可透過一系列區域性的最優解的選擇達到,並且每次的選擇可以依賴以前作出的選擇,但不依賴於後面要作出的選擇。這就是貪心選擇性質。對於一個具體問題,要確定它是否具有貪心選擇性質,必須證明每一步所作的貪心選擇最終導致問題的整體最優解 。

2、最優子結構性質

  當一個問題的最優解包含其子問題的最優解時,稱此問題具有最優子結構性質。問題的最優子結構性質是該問題可用貪心法求解的關鍵所在。在實際應用中,至於什麼問題具有什麼樣的貪心選擇性質是不確定的,需要具體問題具體分析 。

存在問題

貪心演算法也存在如下問題:

  1. 不能保證解是最佳的。因為貪心演算法總是從區域性出發,並沒從整體考慮
  2. 貪心演算法一般用來解決求最大或最小解
  3. 貪心演算法只能確定某些問題的可行性範圍

用例

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....

相關文章