在《算法導論》中舉了買股票和割鐵棒的例子來講明動態規劃和貪心算法的主體思想。c++
貪心算法:老是作出在當前看來最好的狀況。(不是總體最優的)算法
先拋出一個問題,相似於《算法導論》中的股票問題。數組
Find the contiguous subarray within an array (containing at least one number) which has the largest sum.
簡單的一句話歸納,就是找一個數組中擁有最大和的子數組,返回其和。字體
答案(不惟一)只有6行,能夠說是很是簡潔,且便於理解了。ui
/* *@lucastan */
int maxSubArray(vector<int> &nums) {
int ans = nums[0], i, sum = 0;
for(i = 0; i < nums.size(); i++){
sum += nums[i];
ans = max(sum, ans);
sum = max(sum, 0);
}
return ans;
}複製代碼
讀完問題,咱們馬上就能想到的是從頭開始加,總能枚舉出來一個。spa
這個想法能夠說是很是樸實了,可是……咱們仍是繼續思考吧,第二反應就是貪心算法了(若是你能想到動態規劃的思想,也不錯啊,能夠相似的求解)。3d
首先咱們要說,貪心算法的簡單定義是什麼?(答案是白色字體)code
老是找到一個在當前看來最優的解。
而後,咱們如今要求的是什麼?cdn
數組中擁有最大和的子數組。
這樣一來,目標就明確了,咱們確定是須要遍歷數組的,否則怎麼能肯定咱們考慮到了數組中全部元素呢?blog
明確了目標,咱們結合貪心算法的定義,提出下一個問題,咱們怎麼肯定如今的子數組元素的和到目前爲止是最大的呢?
與在添加了下一個元素以前的數組進行比較。
那萬一咱們加到數組的某一個位置的時候,出現了和爲負的狀況……
笨啊,一旦加到某個元素出現和爲負的狀況,咱們就應該捨棄前面的全部元素,而後在下一個元素處從新開始求和。若是等於零,那麼咱們就要從這個元素開始從新求和。
另外,不要鑽最大子數組在中間的這一種狀況的牛角尖,除非在計算時數組前面的元素和小於等於零,不然咱們在這個代碼裏,永遠會獲得[0...x](x表明子數組的最後一個元素序號,[0...x]難道不是他的子數組嗎?就算咱們最後獲得數組自己,他也是該數組的子數組)。
文章看到這裏,可能就有人發現了,這個問題並非真的應用了貪心算法,咱們只是借來了貪心算法一點點的思想,而後就獲得了問題的解答。
(完整的貪心算法思想在這裏是不能應用的,若是題目不要求子數組連續,那麼卻是能夠完整的應用貪心算法思想,但這樣一來問題也就失去了意義。)
看了標題和開頭的一點點胡言亂語,你是否是真的覺得我要講貪心算法了,哼,天真。