<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>BFS on 跟著 Desolve 學程式</title><link>https://desolve.pages.dev/tags/bfs/</link><description>Recent content in BFS on 跟著 Desolve 學程式</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Sun, 28 May 2023 00:00:00 +0800</lastBuildDate><atom:link href="https://desolve.pages.dev/tags/bfs/index.xml" rel="self" type="application/rss+xml"/><item><title>從LeetCode學演算法 - 118 DFS (20) /BFS (5) / Queue (6)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-118-dfs-20-bfs-5-queue-6/</link><pubDate>Sun, 28 May 2023 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-118-dfs-20-bfs-5-queue-6/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 118 DFS (20) /BFS (5) / Queue (6)" /&gt;&lt;p&gt;&lt;strong&gt;0934. Shortest Bridge (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&gt;&lt;p&gt;(基礎+進階+面試篇)從 LeetCode 學演算法 + 面試成功指南**&lt;/p&gt;
&lt;p&gt;(3591元 特價中: 2023/06/30 23:59後截止) &lt;br&gt;
&lt;a class="link" href="https://hiskio.com/bundles/eCP23B397?s=tc" target="_blank" rel="noopener"
&gt;https://hiskio.com/bundles/eCP23B397?s=tc&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(3990元 長期有效) &lt;a class="link" href="https://bit.ly/lc2022all" target="_blank" rel="noopener"
&gt;https://bit.ly/lc2022all&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;容筆者工商一下，&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜進階篇」&lt;/strong&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/lc2022adv" target="_blank" rel="noopener"
&gt;https://bit.ly/lc2022adv&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;You are given an &lt;code&gt;n x n&lt;/code&gt; binary matrix &lt;code&gt;grid&lt;/code&gt; where &lt;code&gt;1&lt;/code&gt; represents land and &lt;code&gt;0&lt;/code&gt; represents water.&lt;/p&gt;
&lt;p&gt;An &lt;strong&gt;island&lt;/strong&gt; is a 4-directionally connected group of &lt;code&gt;1&lt;/code&gt;&amp;rsquo;s not connected to any other &lt;code&gt;1&lt;/code&gt;&amp;rsquo;s. There are ** exactly two islands** in &lt;code&gt;grid&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You may change &lt;code&gt;0&lt;/code&gt;&amp;rsquo;s to &lt;code&gt;1&lt;/code&gt;&amp;rsquo;s to connect the two islands to form &lt;strong&gt;one island&lt;/strong&gt; .&lt;/p&gt;
&lt;p&gt;Return &lt;em&gt;the smallest number of&lt;/em&gt; &lt;code&gt;0&lt;/code&gt;&lt;em&gt;&amp;rsquo;s you must flip to connect the two islands&lt;/em&gt;.&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;/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: grid = [[0,1],[1,0]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 1
&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;/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: grid = [[0,1,0],[0,0,0],[0,0,1]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 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-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;/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: grid = [[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 1
&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="constraints"&gt;Constraints
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;n == grid.length == grid[i].length&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;2 &amp;lt;= n &amp;lt;= 100&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;grid[i][j]&lt;/code&gt; is either &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;There are exactly two islands in &lt;code&gt;grid&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一個 n x n 的 binary 矩陣 grid，當中 1 代表陸地，0 代表水。&lt;br&gt;
一個 island (島嶼) 的定義是指一組在四個方向和其他的1相連的群組，&lt;br&gt;
且沒有再和其他1相連(也就是中間經過1的都算是同一塊島嶼)。&lt;br&gt;
在 grid 中恰好兩塊島嶼。&lt;br&gt;
你可以將0變成1用來連接兩塊島嶼，以形成一塊島嶼，&lt;br&gt;
試回傳要翻轉0到1使得兩塊島嶼連接的最少所需的數目。&lt;/p&gt;
&lt;p&gt;好久不見了！&lt;/p&gt;
&lt;p&gt;這題算是比較特別的題目，因為比較好的解法會是DFS和BFS都用上，&lt;br&gt;
一個用來找到第一整塊島嶼，另一個用來連接。&lt;/p&gt;
&lt;p&gt;就題目而言，從0翻到1，其實就是一個搭橋的概念，&lt;br&gt;
單就grid上考慮，那麼我們肯定是從兩個島距離最近的點來搭會最好，&lt;br&gt;
但怎麼知道哪兩個點距離最近呢？&lt;/p&gt;
&lt;p&gt;如果兩塊島嶼都是完整矩形的話，&lt;br&gt;
或許我們還可以從邊與邊的垂直距離來做文章，&lt;br&gt;
也還有一些比較簡單的計算方法(比如下圖取兩點的垂直+水平距離)&lt;br&gt;
(如果水平或垂直方向有重合的話則只計di或dj)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-118-dfs-20-bfs-5-queue-6/1_jDGWMo9GGc6i3QMe20gCKg.png"
width="542"
height="406"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-118-dfs-20-bfs-5-queue-6/1_jDGWMo9GGc6i3QMe20gCKg_hu_a1b022a123fbc9c0.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-118-dfs-20-bfs-5-queue-6/1_jDGWMo9GGc6i3QMe20gCKg_hu_331d6f44e1a1a444.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;p&gt;取最近的兩點垂直距離+水平距離(也有可能其中一個方向不用計)&lt;/p&gt;
&lt;p&gt;但.…..它們並不一定是矩形XD&amp;quot;&lt;br&gt;
所以有可能出現像這樣子的狀況，然後旁邊可能全是不規則形狀，&lt;br&gt;
無法用矩形算完：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-118-dfs-20-bfs-5-queue-6/1_YyE0BEXcAeg-8lZKxMERwQ.png"
width="543"
height="407"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-118-dfs-20-bfs-5-queue-6/1_YyE0BEXcAeg-8lZKxMERwQ_hu_90d7805b61444ee3.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-118-dfs-20-bfs-5-queue-6/1_YyE0BEXcAeg-8lZKxMERwQ_hu_a079d8be246366e5.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="133"
data-flex-basis="320px"
&gt;&lt;/p&gt;
&lt;p&gt;看圖會知道算哪個點，但究竟要娶幾個點才能算呢？&lt;/p&gt;
&lt;p&gt;所以既然無法知道兩塊島嶼長什麼樣子，也不知道規不規則，&lt;br&gt;
那只能回到笨方法了：&lt;br&gt;
&lt;strong&gt;先找到其中一塊島嶼，再從這塊島嶼的邊界往外找(搭橋)。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我們嘗試來列出解題步驟：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;取得grid的長寬r, c (沒錯，這題其實就算不是正方形的grid應該也可以做)&lt;/li&gt;
&lt;li&gt;先遍歷找到grid上任意一個值為1的點(i, j)，&lt;br&gt;
這個點肯定是其中一塊島上的陸地&lt;/li&gt;
&lt;li&gt;從(i, j)開始進行DFS往四方探索陸地，同時將所有途經的陸地標為2&lt;br&gt;
(標成2的意義是為了可以和另一塊島嶼的陸地區分開來)；&lt;/li&gt;
&lt;li&gt;在步驟3的探索中，如果碰到0時，&lt;br&gt;
把和0相接的陸地座標記到一個&lt;strong&gt;queue&lt;/strong&gt; 裡面&lt;br&gt;
(代表這是第一塊陸地的臨水的邊界)&lt;/li&gt;
&lt;li&gt;完成3, 4後，我們會得到一個queue，當中全是第一個島嶼的&lt;strong&gt;臨水的邊界&lt;/strong&gt; ，&lt;br&gt;
作為我們搭橋的出發點，這裡設定我們要求的答案step為0&lt;/li&gt;
&lt;li&gt;當queue中有值的時候，持續操作以下步驟：&lt;/li&gt;
&lt;li&gt;取得當前queue的長度L，進行一個L次的迴圈：&lt;/li&gt;
&lt;li&gt;從queue中取出一組座標(i, j)&lt;/li&gt;
&lt;li&gt;從(i, j)往四個方向看，如果沒有超出grid的話，檢查以下可能：&lt;br&gt;
9-1. 如果值是1，則代表成功接通，這時候直接回傳step作為答案即可&lt;br&gt;
9-2. 如果值是0，則代表繼續搭橋，將新座標放到queue當中，&lt;br&gt;
並且將這個位置的值標為-1(代表已經走過了)&lt;/li&gt;
&lt;li&gt;步驟7的迴圈結束後，將step遞增1，接下來回到6檢查是否要繼續&lt;/li&gt;
&lt;li&gt;雖然題目設定上一直都是找得到解答的，但如果找不到解答的話，&lt;br&gt;
離開步驟6的迴圈後，則應該要回傳-1，表示找不到能搭建的橋&lt;br&gt;
(也就是grid可能被給成只有一塊土地)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在上面的解題步驟中，步驟3&lt;del&gt;4是&lt;strong&gt;DFS&lt;/strong&gt; ，&lt;br&gt;
目的在於要找到第一塊島嶼，記錄邊界，&lt;br&gt;
並將其值改動成2，用來跟第二塊島嶼區別；&lt;br&gt;
而步驟6&lt;/del&gt;10則是&lt;strong&gt;BFS&lt;/strong&gt; ，&lt;br&gt;
用來從邊界開始往外嘗試搭橋，&lt;br&gt;
因此我們可以在找到連接到第二塊島嶼的時候，&lt;br&gt;
因為一次是每種可能都走一步的特性，確定最小所需的步數，&lt;br&gt;
也就是我們所要求的答案。&lt;/p&gt;
&lt;p&gt;依此，寫成程式碼如下。&lt;/p&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;為求簡單，這邊我們直接將grid改名為A，避免寫太多次。&lt;br&gt;
我們可以利用簡單的dirs串列來標定四個方向，&lt;br&gt;
從而縮減每次寫+1和-1的部分，&lt;br&gt;
這個小技巧應該常碰到類似題目的同學大多看過。&lt;br&gt;
另外，我們使用了一個set start，用來幫我們自動化簡加入的座標，&lt;br&gt;
因為我們有可能加同樣的座標到queue裡面，&lt;br&gt;
使用set可以有效避免這一點。&lt;/p&gt;
&lt;p&gt;同時請留意到當A[x][y] == 0的時候，要加入的是(i, j)歐!&lt;br&gt;
因為我們加入的是陸地的邊界(1)，而不是水(0)，&lt;br&gt;
同理，後面起始的時候因為是從陸地開始起算，&lt;br&gt;
所以step是從0而非從1開始。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/4499fef61fa66238f3dc5f9bd440a703.js"&gt;&lt;/script&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分則會稍微麻煩一點，&lt;br&gt;
這邊將大多數的東西放在class variable的位置，&lt;br&gt;
可以有效避免需要大量的傳遞參數；&lt;br&gt;
Queue的部份我們使用ArrayDeque來處理，&lt;br&gt;
那麼對應的取出和放入就會變成poll()和offer()。&lt;br&gt;
(注意每次放入的時候都要產生一個新的int[]來放入)&lt;/p&gt;
&lt;p&gt;另一方面，由於HashSet在Java當中用起來比較沒有像Python這麼彈性，&lt;br&gt;
這邊採用visited的方式來處理，&lt;br&gt;
我們將已經放入過q的(i, j)在visited中設定為true，&lt;br&gt;
再每次檢查，即可得到相同效果。&lt;br&gt;
此外，由於Java不接受回傳一個沒有回傳值的function，&lt;br&gt;
因此27和28行會分成兩行來寫，先進行dfs完，再呼叫return。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/41cfb3a3f64ec5a73184e9e68eb92667.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(n²)/O(n²)，在長和寬均為n的狀況下，最多也就是掃完整個grid)&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/lc2022base" target="_blank" rel="noopener"
&gt;https://bit.ly/lc2022base&lt;/a&gt;&lt;/p&gt;</description></item><item><title>從LeetCode學演算法 - 113 BFS (4) / Queue (5)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-113-bfs-4-queue-5/</link><pubDate>Tue, 16 Feb 2021 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-113-bfs-4-queue-5/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 113 BFS (4) / Queue (5)" /&gt;&lt;p&gt;&lt;strong&gt;1091. Shortest Path in Binary Matrix (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;/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;In an N by N square grid, each cell is either empty (0) or blocked (1).&lt;/p&gt;
&lt;p&gt;A &lt;em&gt;clear path from top-left to bottom-right&lt;/em&gt; has length &lt;code&gt;k&lt;/code&gt; if and only if it is composed of cells &lt;code&gt;C_1, C_2, ..., C_k&lt;/code&gt; such that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adjacent cells &lt;code&gt;C_i&lt;/code&gt; and &lt;code&gt;C_{i+1}&lt;/code&gt; are connected 8-directionally (ie., they are different and share an edge or corner)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C_1&lt;/code&gt; is at location &lt;code&gt;(0, 0)&lt;/code&gt; (ie. has value &lt;code&gt;grid[0][0]&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;C_k&lt;/code&gt; is at location &lt;code&gt;(N-1, N-1)&lt;/code&gt; (ie. has value &lt;code&gt;grid[N-1][N-1]&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;C_i&lt;/code&gt; is located at &lt;code&gt;(r, c)&lt;/code&gt;, then &lt;code&gt;grid[r][c]&lt;/code&gt; is empty (ie. &lt;code&gt;grid[r][c] == 0&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Return the length of the shortest such clear path from top-left to bottom-right. If such a path does not exist, return -1.&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;/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: [[0,1],[1,0]]
&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;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-113-bfs-4-queue-5/0_gvhwvqTYiqSdw4wb.png"
width="729"
height="735"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-113-bfs-4-queue-5/0_gvhwvqTYiqSdw4wb_hu_941932ac54e24550.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-113-bfs-4-queue-5/0_gvhwvqTYiqSdw4wb_hu_4fd2d15b94fb0d93.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="99"
data-flex-basis="238px"
&gt;&lt;/p&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;/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;Output: 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;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-113-bfs-4-queue-5/0_QarU-KLAhaaM-RzQ.png"
width="729"
height="735"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-113-bfs-4-queue-5/0_QarU-KLAhaaM-RzQ_hu_4b008d791a75b815.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-113-bfs-4-queue-5/0_QarU-KLAhaaM-RzQ_hu_3492327ad3d1ddd.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="99"
data-flex-basis="238px"
&gt;&lt;/p&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;/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: [[0,0,0],[1,1,0],[1,1,0]]
&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;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-113-bfs-4-queue-5/0_fD8h6ClSM12rB3Rb.png"
width="729"
height="735"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-113-bfs-4-queue-5/0_fD8h6ClSM12rB3Rb_hu_2e4721ad3247628.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-113-bfs-4-queue-5/0_fD8h6ClSM12rB3Rb_hu_749828fe35e27331.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="99"
data-flex-basis="238px"
&gt;&lt;/p&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;/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;Output: 4
&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;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-113-bfs-4-queue-5/0_5QjCJsJ3QAXMUYTk.png"
width="729"
height="735"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-113-bfs-4-queue-5/0_5QjCJsJ3QAXMUYTk_hu_6fd53564c1731b44.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-113-bfs-4-queue-5/0_5QjCJsJ3QAXMUYTk_hu_5f5defeb4cff5dbe.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="99"
data-flex-basis="238px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;1 &amp;lt;= grid.length == grid[0].length &amp;lt;= 100&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;grid[r][c]&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;在一個N x N的平方格子裡，每個格子可能是空的(0)，&lt;br&gt;
不然就是阻塞住的(1)。&lt;/p&gt;
&lt;p&gt;一個乾淨的路徑從左上到右下的長度為k，如果路徑上的格子都是8方向(也就是九宮格的對應)相連，且開頭是(0, 0)，結尾是(N-1, N-1)，且每一格都是空的(0)。請回傳從左上到右下最短的乾淨路徑長，若不存在則回傳-1。&lt;/p&gt;
&lt;p&gt;這個題目其實可以有很多種不同的解決方式，&lt;br&gt;
不過我們好久沒有使用到BFS了，就來試試看BFS的解法吧！&lt;br&gt;
根據題目的定義，我們要找的是最短路徑，&lt;br&gt;
所以可以從(0, 0)開始嘗試每次往8個方向各走一步，&lt;br&gt;
並且將計數+1及標記已經走過，當在某步碰到了(N-1, N-1)時，&lt;br&gt;
即表示我們找到了最短路徑(因為所有路線都是每次同時走一步)。&lt;br&gt;
因此，我們需要一個Queue來記錄當前所有走到的點，&lt;br&gt;
然後每次再將Queue的點取出，&lt;br&gt;
找到8個方向的新的一步的點，加入到Queue中。&lt;br&gt;
(不能超出邊界，不能已經走過，也不能被阻擋住)&lt;/p&gt;
&lt;p&gt;那麼我們怎麼知道同一層的要做到哪裡呢？&lt;br&gt;
很簡單，在這層開始之前，我們先記錄下當前Queue的長度，&lt;br&gt;
這樣子同一層只要做完這麼多個點就可以啦！&lt;/p&gt;
&lt;p&gt;依此，寫成程式碼如下：&lt;br&gt;
(下面的程式碼中，我們直接把走過的路徑給標成block了，&lt;br&gt;
這點相對較節省空間也較方便，但其實不是很正規，&lt;br&gt;
如果面試時沒有說你可以動grid，請開出一個N x N的visited格子，&lt;br&gt;
用來記錄有經過的點會比較好呦！)&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分，首先我們先檢查grid的狀況，&lt;br&gt;
以及左上右下是否有阻擋住的狀況，有的話就直接回傳-1。&lt;br&gt;
接著使用LinkedList作為我們的Queue，&lt;br&gt;
可以使用add或者offer來加入新的元素。&lt;br&gt;
當queue不為空時，每次取出一個點，往對應的8個方向取點並檢查：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;走到右下角的話代表走完，直接回傳cnt。&lt;/li&gt;
&lt;li&gt;如果點是合法的點的話，就將那格標記為1並加入queue中。&lt;/li&gt;
&lt;li&gt;每輪做完別忘記將cnt遞增。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;全部做完還沒有碰到右下角，代表沒有解，回傳-1。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/7584199c396a39a577101b136e37b7a1.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分則使用deque來操作，&lt;br&gt;
留意到這個題目其實也可以擴展成矩形，&lt;br&gt;
這邊示範使用r, c的方式來記錄，但其實區別不大。&lt;br&gt;
但對deque來說，取出記得是使用popleft，請不要誤用成pop了！&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/6d86779e734b6b1610ebca1bd1fb0379.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N²)/O(N²)，最糟糕的狀況是擴散的很開的時候，&lt;br&gt;
queue所需要的空間會很大，這個問題其實可以使用bi-directional的BFS來降低擴散的程度，可以再參考leetcode上別人的解法。)&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><item><title>從LeetCode學演算法 - 103 Tree (16) / DFS (13) / BFS (3) / Queue (4)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-103-tree-16-dfs-13-bfs-3-queue-4/</link><pubDate>Sat, 08 Aug 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-103-tree-16-dfs-13-bfs-3-queue-4/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 103 Tree (16) / DFS (13) / BFS (3) / Queue (4)" /&gt;&lt;p&gt;&lt;strong&gt;0112. Path Sum (Easy)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&gt;&lt;p&gt;容筆者工商一下， &lt;strong&gt;「從Leetcode學演算法｜進階篇」及&lt;/strong&gt; 加贈的**「從Leetcode學演算法｜面試篇」已經全數上傳完囉！**&lt;/p&gt;
&lt;p&gt;目前只剩下給讀者的&lt;strong&gt;進階篇+面試篇(3150)&lt;/strong&gt; 和&lt;strong&gt;全套同捆優惠(3990)&lt;/strong&gt; 了QQ&lt;br&gt;
「從Leetcode學演算法｜進階篇」+「從Leetcode學演算法｜面試篇」：&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;br&gt;
「從Leetcode學演算法」全套(基礎/進階/面試篇)同捆優惠：&lt;br&gt;
&lt;a class="link" href="https://bit.ly/leetcodeall" target="_blank" rel="noopener"
&gt;https://bit.ly/leetcodeall&lt;/a&gt;&lt;/p&gt;
&lt;p&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;/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;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A leaf is a node with no children.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Given the below binary tree and &lt;code&gt;sum = 22&lt;/code&gt;,&lt;/p&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;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;4
&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;5
&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;6
&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;7
&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; 5
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; / \
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 4 8
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; / / \
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 11 13 4
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; / \ \
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;7 2 1
&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;return true, as there exists a root-to-leaf path &lt;code&gt;5-&amp;gt;4-&amp;gt;11-&amp;gt;2&lt;/code&gt; which sum is 22.&lt;/p&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一棵二元樹，試決定該二元樹是否有一個從根到葉的路徑，&lt;br&gt;
使得路徑上的節點總和恰等於給定的目標和。&lt;/p&gt;
&lt;p&gt;這一題是一整組Path Sum系列題的第一題，&lt;br&gt;
除了接下來幾篇會陸續談到系列題外，這篇也想著重給讀者一個提醒：&lt;br&gt;
&lt;strong&gt;很多時候能用DFS解的題目，通常也能用BFS解&lt;/strong&gt; (反之亦然)&lt;/p&gt;
&lt;p&gt;所以當下遇到一個題目的時候，除非有限定要求，&lt;br&gt;
否則只要&lt;strong&gt;能想到的解法就是好解法&lt;/strong&gt; ，&lt;br&gt;
不要硬逼自己一定要用DFS或一定要用BFS。&lt;br&gt;
(練習的時候，當然還是可以自我挑戰兩種都想出解來就是了XD)&lt;/p&gt;
&lt;p&gt;首先我們要留意到一件事情：&lt;br&gt;
由於是從根到葉，&lt;br&gt;
所以我們只需要在走到左右均無節點時再檢查總和是否相符即可，&lt;br&gt;
千萬不要沿途檢查呀XD！&lt;/p&gt;
&lt;p&gt;再者，由於路途經過的都會算做計入的總和，&lt;br&gt;
所以我們可以沿路將往下走所需的總和減去當前經過的節點。&lt;/p&gt;
&lt;p&gt;依照這個概念，我們可以蠻直觀地寫出一個DFS的解：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先檢查&lt;strong&gt;root如果是NIL -&amp;gt; 直接回傳False&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;檢查&lt;strong&gt;root.left/root.right&lt;/strong&gt; 是不是&lt;strong&gt;都為NIL&lt;/strong&gt; -&amp;gt; 若均為NIL，&lt;br&gt;
若&lt;strong&gt;root.val等於所需和&lt;/strong&gt; 則回傳&lt;strong&gt;True&lt;/strong&gt; ，&lt;strong&gt;否則回傳False&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;將往下走的剩下的和next定為sum — root.val(剩下需要湊的和)&lt;/li&gt;
&lt;li&gt;回傳&lt;strong&gt;hasPathSum(root.left, next) || hasPathSum(root.right, next)&lt;/strong&gt; (因為只要存在一條路徑即為True，所以兩者用&lt;strong&gt;或&lt;/strong&gt; 來連接)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;由上可知，用來判定這個位置能不能成為我們要的路徑和，&lt;br&gt;
只取決於兩點：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;現在這個位置是否已經是葉(leaf)&lt;/li&gt;
&lt;li&gt;現在這個位置的値是否是剩下需要的和&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以我們也可以用BFS的方式，搭配前面講過的Queue來處理：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;同樣先檢查root及處理回傳&lt;/li&gt;
&lt;li&gt;將**[(root, sum - root.val)]** 放入Queue當中&lt;/li&gt;
&lt;li&gt;進行迴圈，每次從Queue中取出一組**(curr, val)** 並檢查：&lt;br&gt;
3–1. 若curr.left/curr.right&lt;strong&gt;均為NIL&lt;/strong&gt; -&amp;gt; ** 若val為0，回傳True**&lt;br&gt;
3–2. 檢查curr.left，若存在 -&amp;gt; 將**(curr.left, val - curr.left.val)放入Queue** 中&lt;br&gt;
3–3. 對curr.right做相同處理&lt;/li&gt;
&lt;li&gt;若迴圈結束仍未回傳，則&lt;strong&gt;回傳Fals&lt;/strong&gt; e(找不到適合的路徑)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;依上面的方式，我們分別在Java/Python演示不同的方法：&lt;br&gt;
(讀者也可以自行嘗試完整練完單一語言的DFS/BFS的方法)&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分，使用了DFS，所以整體而言看起來很簡單，&lt;br&gt;
不過原則上有用遞迴的題目，就盡量要留意call stack的深度會不會超過。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/ef96d203f2d348e11ecc39418a6ddb46.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分則使用了BFS，搭配deque做為queue使用，&lt;br&gt;
留意當val != 0的時候記得要繼續操作，因為你可能會有其他節點符和XD，&lt;br&gt;
這點和DFS時不一樣，請特別留意不要直接在那邊回傳False呦！&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/43e22de9d28607e24276588dc0aaf675.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N)/O(log N)或O(N)(平均)，&lt;br&gt;
因為DFS的話記憶體計算call stack深度，&lt;br&gt;
BFS的話則是要用最底部的橫向長度來看；&lt;br&gt;
如果極端的狀況的話DFS也有可能到O(N)，因為樹可能不平衡)&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;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><item><title>從LeetCode學演算法 - 46 BFS (2) / Queue (3)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-46-bfs-2-queue-3/</link><pubDate>Sat, 07 Sep 2019 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-46-bfs-2-queue-3/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 46 BFS (2) / Queue (3)" /&gt;&lt;p&gt;&lt;strong&gt;0199. Binary Tree Right Side View (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;另外筆者昨天生日，快補祝我生日快樂XDDDDD&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a binary tree, imagine yourself standing on the &lt;em&gt;right&lt;/em&gt; side of it, return the values of the nodes you can see ordered from top to bottom.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&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: [1,2,3,null,5,null,4]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [1, 3, 4]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation:
&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;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;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;4
&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;5
&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; 1 &amp;lt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; / \
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2 3 &amp;lt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; \ \
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 5 4 &amp;lt;---
&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="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一棵二元樹，想像你站在樹的右邊往左看，&lt;br&gt;
試回傳從上到下依序所看到的值。&lt;/p&gt;
&lt;p&gt;這題一看就知道某種程度上屬於level-order traversal，&lt;br&gt;
(還不清楚或不知道什麼是level-order的讀者請參閱&lt;a class="link" href="../learn-algorithm-from-leetcode-43-bfs-1-queue-2" &gt;這篇&lt;/a&gt;)&lt;br&gt;
只是要求的部分有點不一樣而已，這邊只要求最右邊的數字。&lt;/p&gt;
&lt;p&gt;那麼要注意囉！可能會有人想，我能不能&lt;strong&gt;只走最右邊&lt;/strong&gt; 取值就好呢？&lt;br&gt;
答案是當然不行！！！因為你可能會遇到類似這樣的狀況：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-46-bfs-2-queue-3/image-001.png"
width="298"
height="228"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-46-bfs-2-queue-3/image-001_hu_7cb11bee5f488546.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-46-bfs-2-queue-3/image-001_hu_7cbda7f5d477aa3b.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="130"
data-flex-basis="313px"
&gt;&lt;/p&gt;
&lt;p&gt;你看到的最右邊不是人家的最右邊XD&lt;/p&gt;
&lt;p&gt;如果只取最右邊的話，顯然我們會走1-3-0然後就結束了，&lt;br&gt;
但還有一個4落在中間，所以這題無論如何還是要乖乖遍歷所有節點才行。&lt;/p&gt;
&lt;p&gt;我們可以用BFS的方式來解這題(DFS也行，但要用到遞迴，這裡暫不討論)，步驟如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先新增一個queue用來存放當層(level)的所有節點，&lt;br&gt;
另外開一個串列res(result)用來存放結果。&lt;/li&gt;
&lt;li&gt;記錄當下queue的總數cnt(count)。&lt;/li&gt;
&lt;li&gt;執行一個cnt次數的迴圈，依序將當層的節點取出&lt;/li&gt;
&lt;li&gt;每取出一個節點，就分別檢查其左右節點是否存在，&lt;br&gt;
存在則以&lt;strong&gt;先左後右&lt;/strong&gt; 的順序放入queue中。&lt;/li&gt;
&lt;li&gt;迴圈執行完後，queue中應該全是下一層的節點；&lt;br&gt;
同時&lt;strong&gt;最後一個取出的節點&lt;/strong&gt; ，就是每層最右邊的節點，&lt;br&gt;
將其值取出放入res中。&lt;/li&gt;
&lt;li&gt;重複2~5的動作，直到queue中沒有節點為止。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;讀者會發現這樣的做法唯一的差別就是要&lt;strong&gt;記錄最後一個取出的節點&lt;/strong&gt; ，&lt;br&gt;
其他和level-order traversal一樣，利用queue先進先出的原則，&lt;br&gt;
每次恰好處理一層的節點。&lt;/p&gt;
&lt;p&gt;依此我們可以寫成程式碼，&lt;br&gt;
Java的部分List和Queue都可以使用LinkedList，&lt;br&gt;
且TreeNode的部分由於Java必須給定值，故一開始last先行給定為null。&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/110dada57bc59c4a1eec9b141779b19f.js"&gt;&lt;/script&gt;
&lt;p&gt;Python的部分不要忘記當需要從左邊取值時&lt;strong&gt;deque&lt;/strong&gt; 的速度會較List快，&lt;br&gt;
另外last其實可以不用先給值也可以順利通過。&lt;/p&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/65975540d83a1c1f23de9bfa9a2c7f91.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N), O(N)，每個節點都會遍歷過，&lt;br&gt;
同時因為使用Queue的時候中間會儲存整個level，&lt;br&gt;
空間複雜度還是跟總數相關。)&lt;/p&gt;
&lt;p&gt;「可以使用DFS嗎？」&lt;br&gt;
(可以，但需要對每項記錄其level，解法相對較難處理，讀者可嘗試看看)&lt;/p&gt;
&lt;p&gt;「如果題目改成從左邊看呢？」&lt;br&gt;
(一樣要遍歷所有節點，但改成在每一層的第一項就將值置入到答案中)&lt;/p&gt;
&lt;h2 id="相似及延伸"&gt;相似及延伸
&lt;/h2&gt;&lt;p&gt;1.&lt;a class="link" href="https://leetcode.com/problems/binary-tree-level-order-traversal/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;0102. Binary Tree Level Order Traversal&lt;/strong&gt; &lt;/a&gt;&lt;/p&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;</description></item><item><title>從LeetCode學演算法 - 43 BFS (1) / Queue (2)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-43-bfs-1-queue-2/</link><pubDate>Sat, 31 Aug 2019 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-43-bfs-1-queue-2/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 43 BFS (1) / Queue (2)" /&gt;&lt;p&gt;&lt;strong&gt;1161. Maximum Level Sum of a Binary Tree (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given the &lt;code&gt;root&lt;/code&gt; of a binary tree, the level of its root is &lt;code&gt;1&lt;/code&gt;, the level of its children is &lt;code&gt;2&lt;/code&gt;, and so on.&lt;/p&gt;
&lt;p&gt;Return the &lt;strong&gt;smallest&lt;/strong&gt; level &lt;code&gt;X&lt;/code&gt; such that the sum of all the values of nodes at level &lt;code&gt;X&lt;/code&gt; is ** maximal**.&lt;/p&gt;
&lt;h3 id="example-1"&gt;Example 1
&lt;/h3&gt;&lt;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-43-bfs-1-queue-2/image-001.JPG"
width="332"
height="291"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-43-bfs-1-queue-2/image-001_hu_638d66e10e3ecdaf.JPG 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-43-bfs-1-queue-2/image-001_hu_590d60ed387b6aa9.JPG 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="114"
data-flex-basis="273px"
&gt;&lt;/p&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;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;4
&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;5
&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;6
&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;7
&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: [1,7,0,7,-8,null,null]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Level 1 sum = 1.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Level 2 sum = 7 + 0 = 7.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Level 3 sum = 7 + -8 = -1.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;So we return the level with the maximum sum which is level 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;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The number of nodes in the given tree is between &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;10^4&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-10^5 &amp;lt;= node.val &amp;lt;= 10^5&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一個二元樹的根節點，若將該層(level)稱為1，&lt;br&gt;
其子節點所在層稱為2，……以此類推，&lt;br&gt;
嘗試找出最小的x層，這層的所有節點和是在所有層裡面&lt;strong&gt;最大的&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;這題其實存在不同的解法，若讀者有興趣的話也可以使用DFS的解法，&lt;br&gt;
本篇只介紹BFS的作法。&lt;/p&gt;
&lt;p&gt;如果有看過先前對於&lt;a class="link" href="https://medium.com/@desolution/%E5%BE%9Eleetcode%E5%AD%B8%E6%BC%94%E7%AE%97%E6%B3%95-13-tree-1-52cfbdde02b2" target="_blank" rel="noopener"
&gt;Tree的介紹&lt;/a&gt;的話，&lt;br&gt;
我們應該有提到過不同方式的走訪，而這題問的，&lt;br&gt;
如果限定在迭代法解的話，就適合使用&lt;strong&gt;層序走訪(level-order traversal)&lt;/strong&gt; 。&lt;br&gt;
層序走訪的概念很簡單：&lt;br&gt;
&lt;strong&gt;每次先走完這一層的所有節點，再走下一層的所有節點&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;用遞迴來看的話顯然是沒辦法的，&lt;br&gt;
因為每次往下都是&lt;strong&gt;走往下一層&lt;/strong&gt; (左子樹或右子樹)，&lt;br&gt;
所以我們需要用非遞迴的方式，並使用Queue來作輔助。&lt;/p&gt;
&lt;p&gt;大概步驟會像這樣子：(下面將Queue命名為q)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;將根節點放入q中&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;當q中有節點時，先求&lt;strong&gt;q現在的節點數量cnt&lt;/strong&gt;&lt;br&gt;
(註：這個節點數量就是&lt;strong&gt;目前這整層的所有節點數&lt;/strong&gt; )&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;開始一個迴圈，這個&lt;strong&gt;迴圈執行cnt次&lt;/strong&gt; :&lt;br&gt;
3-a. 每次從q中&lt;strong&gt;取出一個節點n&lt;/strong&gt; ，並&lt;strong&gt;將其值加到當前總和total&lt;/strong&gt; 中&lt;br&gt;
3-b. 檢查左右節點，如果&lt;strong&gt;不是NIL則放進q中&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;(註：第3步做完以後，&lt;br&gt;
q中前一層的cnt個節點應該已經全數移除，並加入下一層的所有節點)&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;檢查&lt;strong&gt;total是否大於當前的最大總和&lt;/strong&gt; ，&lt;br&gt;
若是，則替換掉&lt;strong&gt;最大總和&lt;/strong&gt; 及&lt;strong&gt;所求答案的層數&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;遞增當前的層數(level)&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;重複2~5的動作，&lt;strong&gt;直到q中沒有任何節點為止&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;由上面的步驟可知，每一次我們均藉由Queue來&lt;strong&gt;走遍所有同一層&lt;/strong&gt; 的節點。&lt;br&gt;
在非樹的題目中，類似的作法是先走所有離自己一步距離的可能，&lt;br&gt;
再往下一層去處理，由於是&lt;strong&gt;先求廣度&lt;/strong&gt; ，&lt;br&gt;
這樣子的作法我們稱之為&lt;strong&gt;廣度優先搜尋(BFS, Breadth-First Search)&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;Java的部分，我們可以使用不同的Queue的實作方式，&lt;br&gt;
讀者可以選用ArrayList, LinkedList或ArrayDeque。&lt;br&gt;
(一般來說ArrayList效率會較差，&lt;br&gt;
有人說ArrayDeque號稱比LinkedList好，&lt;br&gt;
但筆者實測看起來沒有明顯差異XD)&lt;/p&gt;
&lt;p&gt;Java的Queue放入和取出的寫法是&lt;strong&gt;offer/poll&lt;/strong&gt; ，總數使用&lt;strong&gt;size&lt;/strong&gt; ，&lt;br&gt;
檢查是否為空則用&lt;strong&gt;isEmpty&lt;/strong&gt; 。&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/cc27cb81a0ce244b5d497f33b13096bd.js"&gt;&lt;/script&gt;
&lt;p&gt;Python的部分則使用前面提過的&lt;strong&gt;deque&lt;/strong&gt; 來處理，&lt;br&gt;
放入和取出分別是&lt;strong&gt;append&lt;/strong&gt; 跟&lt;strong&gt;popleft&lt;/strong&gt; ，總數使用&lt;strong&gt;len&lt;/strong&gt; ，&lt;br&gt;
是否為空則直接&lt;strong&gt;拿其本體來判斷&lt;/strong&gt; (&lt;strong&gt;裡面是空的則會是False&lt;/strong&gt; )&lt;/p&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/9623824b411116f828b1c3cea78a3dfd.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N), O(N)，因為會遍歷整棵樹，而空間占用最大的時候會占用最下面的一整層，所以最糟的狀況也會是O(N)。)&lt;/p&gt;
&lt;p&gt;「題目有告訴我們node總數最大是10^4，如果這棵二元樹是處在平衡的狀態的話，有沒有比較方便的解法？」&lt;br&gt;
(平衡二元樹代表中間該填滿的都填滿了，&lt;br&gt;
所以可以利用這點去算最大的層數，&lt;br&gt;
新增一個陣列/串列來記錄某一層的總和；&lt;br&gt;
直接利用層數來進行DFS，將走到的點的值加到對應的位置，&lt;br&gt;
最後加總完以後再來看哪一個level總和最大。)&lt;/p&gt;
&lt;p&gt;「可以用DFS來解這題看看嗎？」&lt;br&gt;
(可以，只是traversal的時候記得要傳遞層數的值，&lt;br&gt;
並且開一個ArrayList/List來存放每層的總和。)&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;</description></item></channel></rss>