<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Greedy Algorithm on 跟著 Desolve 學程式</title><link>https://desolve.pages.dev/tags/greedy-algorithm/</link><description>Recent content in Greedy Algorithm on 跟著 Desolve 學程式</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Sun, 17 Jan 2021 00:00:00 +0800</lastBuildDate><atom:link href="https://desolve.pages.dev/tags/greedy-algorithm/index.xml" rel="self" type="application/rss+xml"/><item><title>從LeetCode學演算法 - 110 Array (16) / Greedy Algorithm (1)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-110-array-16-greedy-algorithm-1/</link><pubDate>Sun, 17 Jan 2021 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-110-array-16-greedy-algorithm-1/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 110 Array (16) / Greedy Algorithm (1)" /&gt;&lt;p&gt;&lt;strong&gt;0881. Boats to Save People (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&gt;&lt;p&gt;目前&lt;strong&gt;0元挑戰賽&lt;/strong&gt; 的活動已經開始囉！&lt;br&gt;
只要&lt;strong&gt;修課後三個月內完課且成功錄取新工作並撰寫心得，&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;課程就會全額退費喲！請使用下面連結看更詳細的規則說明：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;零元求職挑戰賽 Python 組｜從 LeetCode 學演算法 + 面試成功指南&lt;/strong&gt; &lt;a class="link" href="https://bit.ly/zeroclg?fbclid=IwAR0cGOc6L5R4j26i6BqncG0m1tPPPx5-Z1M0vAOzJpnwUrByX3q-gWE1Sfw" target="_blank" rel="noopener"
&gt;http://bit.ly/zeroclg&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;抽獎活動還在繼續累積人數(現在好像沒有人想抽XD)&lt;br&gt;
在&lt;a class="link" href="https://www.facebook.com/groups/pythontw/permalink/10160354153893438/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Python Taiwan的連結第100篇的文章&lt;/strong&gt; &lt;/a&gt;底下，&lt;br&gt;
&lt;strong&gt;公開分享到你的臉書、按讚該篇文章、並留言告訴我說，&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;「你最喜歡這一整個系列的哪一篇？為什麼？」或&lt;br&gt;
「除了從LeetCode學演算法系列以外，&lt;br&gt;
你還想要看到關於什麼方向的文章？」&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;超過20則留言的話&lt;/strong&gt; (有完成以上步驟的才算)，我們就抽一組&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜進階篇」+「從Leetcode學演算法｜面試篇」&lt;br&gt;
課程的免費兌換券進行贈送！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;期限嘛…就延長到滿人數吧XDD (不然也沒辦法哈哈)&lt;/p&gt;
&lt;p&gt;容筆者工商一下，&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜進階篇」&lt;/strong&gt; 開放預購啦！&lt;br&gt;
這次選了40道難度加深的LeetCode題目，&lt;br&gt;
同樣也會細部解說對應的技巧及須要掌握的演算法！&lt;br&gt;
同時這次購買進階篇的話，&lt;br&gt;
額外還加贈**「從Leetcode學演算法｜面試篇」** ！&lt;br&gt;
當中包含了&lt;strong&gt;面試準備須知分享&lt;/strong&gt; ，&lt;strong&gt;及訪談國內外不同經驗的工程師&lt;/strong&gt; ，&lt;br&gt;
讓你不論是&lt;strong&gt;想走前端/後端/一般軟工&lt;/strong&gt; 或者是&lt;strong&gt;想找國外的工作&lt;/strong&gt; ，&lt;br&gt;
是&lt;strong&gt;初學想轉職&lt;/strong&gt; 還是&lt;strong&gt;正在工作&lt;/strong&gt; ，都能夠從中得到收穫呦！&lt;br&gt;
有興趣的朋友可以使用下面的早鳥優惠～&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜進階篇」+「從Leetcode學演算法｜面試篇」&lt;/strong&gt; ：&lt;br&gt;
&lt;a class="link" href="https://bit.ly/leetcodeadv" target="_blank" rel="noopener"
&gt;https://bit.ly/leetcodeadv&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;i&lt;/code&gt;-th person has weight &lt;code&gt;people[i]&lt;/code&gt;, and each boat can carry a maximum weight of &lt;code&gt;limit&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Each boat carries at most 2 people at the same time, provided the sum of the weight of those people is at most &lt;code&gt;limit&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Return the minimum number of boats to carry every given person. (It is guaranteed each person can be carried by a boat.)&lt;/p&gt;
&lt;h3 id="example-1"&gt;Example 1
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: people = [1,2], limit = 3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: 1 boat (1, 2)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-2"&gt;Example 2
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: people = [3,2,2,1], limit = 3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: 3 boats (1, 2), (2) and (3)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-3"&gt;Example 3
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: people = [3,5,3,4], limit = 5
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 4
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: 4 boats (3), (3), (4), (5)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;1 &amp;lt;= people.length &amp;lt;= 50000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1 &amp;lt;= people[i] &amp;lt;= limit &amp;lt;= 30000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;有一群人people，當中第i個人的重量是people[i]，&lt;br&gt;
且每艘船最重可以載重limit，同時最多只能乘載2個人，&lt;br&gt;
乘載的重量最多為limit(剛好的話也可以)&lt;br&gt;
試計算並回傳最少所需裝載所有人的船的數量。&lt;/p&gt;
&lt;p&gt;乍看之下，這題是不是有點像以前的Two Sum?&lt;br&gt;
但再仔細想想，就會發現，&lt;br&gt;
由於我們並不一定要每艘船都裝載到limit的重量，&lt;br&gt;
所以並不能夠形成相加等於特定和的關係。&lt;/p&gt;
&lt;p&gt;那麼該怎麼處理呢？&lt;br&gt;
如果這群人是由小到大排列的話，&lt;br&gt;
不管如何最重的那些人都還是要上船，&lt;br&gt;
所以我們先挑最右邊的(最重的人)上船。&lt;br&gt;
接下來這艘船還能不能帶人呢？&lt;br&gt;
我們就再幫忙找最左邊的(最輕的人)看能不能湊一組，&lt;br&gt;
可以湊就沒問題，不能湊也無法強求，就只好讓這個人自己一條船囉！&lt;br&gt;
這樣搭配下，我們就可以盡可能先幫較重的人找看看能不能組起來，&lt;br&gt;
因此會是所需求的船隻數量會是最小的。&lt;/p&gt;
&lt;p&gt;上面這樣子的概念，被稱為&lt;strong&gt;貪婪演算法(Greedy Algorithm)&lt;/strong&gt; 。&lt;br&gt;
貪婪演算法的核心精神，在於先找到一個方法，&lt;br&gt;
使得每次盡可能都處理所有可以操作的單位，&lt;br&gt;
再依序往下做處理，這樣的方法是&lt;strong&gt;對總體來說也是最佳&lt;/strong&gt; 的時候，&lt;br&gt;
就符合貪婪演算法的特性。&lt;br&gt;
請讀者務必留意，&lt;br&gt;
如果像是&lt;strong&gt;動態規劃(Dynamic Programming)&lt;/strong&gt; 這類型的問題，&lt;br&gt;
就顯然&lt;strong&gt;不會符合&lt;/strong&gt; 貪婪演算法的作法，&lt;br&gt;
因為&lt;strong&gt;局部的最佳解，不見得會是全局的最佳解&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;所以對這題來說，當我們排序完這群人以後，&lt;br&gt;
從最重的開始盡可能幫其安排組合，對總體來說就會是最好的。&lt;/p&gt;
&lt;p&gt;因此，我們的大體解法應該如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先將people由小到大排序&lt;/li&gt;
&lt;li&gt;令&lt;strong&gt;l = 0, r = people.length - 1, res = 0 (用來記錄需要幾艘船)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;使用一個迴圈，當 &lt;strong&gt;l ≤ r&lt;/strong&gt; 時，進行以下操作：&lt;br&gt;
3–1. 如果 &lt;strong&gt;people[l]+people[r]&amp;lt;= limit&lt;/strong&gt; 時，&lt;br&gt;
代表可以捎上&lt;strong&gt;index l&lt;/strong&gt; 的人，此時將** l&lt;strong&gt;遞增。&lt;br&gt;
3–2. 由於&lt;/strong&gt;所有人的重量都一定小於limit** ，(題目說的)&lt;br&gt;
所以&lt;strong&gt;people[r]一定可以占一艘船&lt;/strong&gt; (不管people[l]有沒有上船)，&lt;br&gt;
所以我們將&lt;strong&gt;r遞減&lt;/strong&gt; ，並且將&lt;strong&gt;res遞增&lt;/strong&gt; ，這艘船我們就處理完囉！&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;回傳res&lt;/strong&gt; 即為答案。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;讀者可能會問：咦？那&lt;strong&gt;l和r重疊&lt;/strong&gt; 的話怎麼辦？&lt;br&gt;
問得好！重疊的話，由於不論怎麼樣r都會遞減，&lt;br&gt;
所以重疊的時候，事實上就是相&lt;strong&gt;當於3–1沒有任何作用&lt;/strong&gt; ，&lt;br&gt;
但並沒有影響到我們要計算的res，對吧XD？&lt;/p&gt;
&lt;p&gt;依此，寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的話使用Arrays.sort()，&lt;br&gt;
其他部分應該相當直觀。&lt;br&gt;
這裡提供LeetCode的另一種解法，&lt;br&gt;
由於有limit的限制，所以我們可以利用長度為limit+1的陣列，&lt;br&gt;
來達到排序的效果(這相當於O(limit)的空間去換取時間複雜度降低)&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/c17604819bd171671e5a4a3cd1dc299c.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的排序則直接對串列進行.sort()即可，&lt;br&gt;
讀者請記得sorted()函式是產生一個新的排序的串列，別搞混喲！&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/c315324b270acabd8a584d6b8554adf8.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(NlogN)/O(1)，N為people的長度。&lt;br&gt;
如果是使用Java附上的參考解的話則是O(limit)/O(limit))&lt;/p&gt;
&lt;h2 id="相似及延伸"&gt;相似及延伸
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Special Thanks suggestions/corrections from viewers:&lt;br&gt;
(歡迎提供意見協助更正歐~)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;從LeetCode學演算法，我們下次見囉，掰~&lt;/p&gt;
&lt;p&gt;想看看其他題目嗎？&lt;br&gt;
歡迎從&lt;a class="link" href="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-0/" &gt;&lt;strong&gt;第零篇&lt;/strong&gt; &lt;/a&gt;找你想要的！&lt;/p&gt;
&lt;p&gt;同時追蹤粉專以獲得更多新文章的通知：&lt;br&gt;
&lt;a class="link" href="https://www.facebook.com/learnwithdesolve" target="_blank" rel="noopener"
&gt;&lt;strong&gt;跟著Desolve學程式&lt;/strong&gt; &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;另外，&lt;strong&gt;「從Leetcode學演算法｜基礎篇」&lt;/strong&gt; 已經回原價囉，&lt;br&gt;
先前的優惠碼會失效，但這邊仍然為讀者保留了300塊的折抵，&lt;br&gt;
雖然&lt;strong&gt;整捆一起買總體比較划算&lt;/strong&gt; (差290而已就有整組了阿XD)，&lt;br&gt;
如果你還是想先試試基礎課的話，&lt;br&gt;
&lt;strong&gt;300元折抵的連結&lt;/strong&gt; 在這邊：&lt;br&gt;
&lt;a class="link" href="https://bit.ly/1desolve" target="_blank" rel="noopener"
&gt;https://bit.ly/1desolve&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>