leetcode 贪心_贪心算法:给我最好的,现在就要!
每次做選擇的時候都做出當下最好的選擇,而不考慮將來的后果。并且期望最終得到的結果是全局最優的。
——貪心算法 - Greedy Algorithm
什么時候該使用貪心算法
針對一組數據,定義了限制值。現在需要我們從中選出幾個數據,在滿足限制值的情況下,使期望值最大。這個不難理解,比如知乎上這個很火的問題:如果帶著一百萬人民幣回到1997年,你會做什么投資? 對于這個問題,一百萬和1997年就是限制值,你在這個條件下可選的各種投資方案就是上面說的“一組數據”,要做的就是經過我們的運作將收益最大化(使期望值最大)。很明顯貪心的我們會優先選擇低成本而高回報的項目。
使用貪心算法的例子
- 分糖果
- 無重疊區間
- 錢幣找零
分糖果
我們要把m個大小不同的糖果分給n個貪婪不一的孩子,糖果的大小大于或等于孩子的滿足感時才能滿足這個孩子,怎樣才能滿足讓盡量多孩子滿足?在這個例子中,限制了糖果的數量,并期望滿足盡量多孩子,這就要求我們運用恰當的方式來選出盡量多的孩子。小孩子是天真的,成年人是貪心的。只需要用剛好能滿足孩子的糖果就能使他滿足,我們就分小糖果給滿足感低的孩子,大糖果可以用來滿足滿足度高的孩子,這樣就可以滿足盡量多的孩子。所以我們的做法是:挑出滿足度最低的孩子,給他最小的能滿足他的糖果,重復這個操作直到糖果分完。
LeetCode#455. 分發餅干:Assign cookies
public int findContentChildren(int[] g, int[] s) {Arrays.sort(g); // 將孩子的滿足度從小到大排序Arrays.sort(s); // 將糖果的大小從小到大排序int gi = 0, si = 0;while(gi < g.length && si < s.length){if(g[gi] <= s[si]){gi++; // 當前小孩子得到滿足,就換下一個孩子}si++; // 當前的糖果分出去就換下一個糖果;沒有分出去就說明這個糖果太小沒人要,也得換下一個糖果}return gi;}無重疊區間
給定n個區間和每個區間的起始與結束坐標,這些區間可能存在重疊的情況,我們要移除掉一些區間以使剩下的區間不重疊,最少要移除多少個區間?假設給定一組區間為:[[6, 8], [2, 4], [3, 5], [1, 5], [5, 9], [8, 10]],求最少需要移除多少個區間。為了保留更多區間,保留下來的區間就應該盡量下且互相不重疊。我們先將所有區間按照結束位置end來排序,由于排序之后end越小的區間的位置就更靠左,留給右邊的位置也越多,就能選擇出更多的區間。如此一來,只要將排序后的區間遍歷一遍,如果當前區間的開始位置小于前一個區間的結束位置,就說明產生了重疊應該移除掉;否則就是應該保留的區間。
排序后的區間LeetCode#435. 無重疊區間:Non-overlapping Intervals
class Solution {public int eraseOverlapIntervals(int[][] intervals) {if(intervals == null || intervals.length < 1) return 0;int cnt = 0;// 先按每個區間的end排序Arrays.sort(intervals, new MyComparator());int end = intervals[0][1];for(int i = 1; i < intervals.length; i++){// 如果當前得start 小于之前的 end,就說明有重合,需要移除。則計數并跳過本次循環if(intervals[i][0] < end){cnt++;}else{end = intervals[i][1];}}return cnt;}class MyComparator implements Comparator<int[]>{@Overridepublic int compare(int[] a, int[] b){return a[1] - b[1];}} }錢幣找零
這是個很貼近日常生活的例子。假如我們有面值為1、5、10、50、100的紙幣若干,它們的張數分別為c1、c5、c10、c50、c100。現在我們需要支付K元,最少需要多少張紙幣呢?在支付額K恒定時,要想付出更少的紙幣數量,就要優先使用大面值來支付。限定值是金額K,而期望是付出最少紙幣數量。假設買了一個烤冷面,需要398元。先從包里數三張100的紅票票,此時還差98元;再來一張50的,還差48;二十元的面值不流通了,我們只好拿出4張10元的;最后是一張5元和4張1元烤冷面就到手了。當然還有一個問題是我們的紙幣數量有限,如果我們沒有三張100元,就要提前讓50元登場。這個問題你理解了嗎?沒理解也沒關系,請出示你的付款碼,我掃你。
小結
其實在能用貪心算法的場景中,貪心都是能得到最優解的。在數學上也是可以證明最優解的有效性的。貪心算法適用的場景就那些,只要多多練習當你再次碰見這些場景時就能游刃有余得想出解題思路了。
知乎用戶?www.zhihu.com貪心算法的應用
- 對數據壓縮編碼的霍夫曼編碼(Huffman Coding)
- 求最小生成樹的Prim算法和Kruskal算法
- 求單源最短路徑的Dijkstra算法
總結
以上是生活随笔為你收集整理的leetcode 贪心_贪心算法:给我最好的,现在就要!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 同学, 你的板砖呢?
- 下一篇: service 层 拼接的html 代码