<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Backtracking on 跟著 Desolve 學程式</title><link>https://desolve.pages.dev/tags/backtracking/</link><description>Recent content in Backtracking on 跟著 Desolve 學程式</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Wed, 20 Jan 2021 00:00:00 +0800</lastBuildDate><atom:link href="https://desolve.pages.dev/tags/backtracking/index.xml" rel="self" type="application/rss+xml"/><item><title>從LeetCode學演算法 - 111 DFS (18) / Backtracking (8)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-111-dfs-18-backtracking-8/</link><pubDate>Wed, 20 Jan 2021 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-111-dfs-18-backtracking-8/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 111 DFS (18) / Backtracking (8)" /&gt;&lt;p&gt;&lt;strong&gt;0784. Letter Case Permutation (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;Given a string S, we can transform every letter individually to be lowercase or uppercase to create another string.&lt;/p&gt;
&lt;p&gt;Return &lt;em&gt;a list of all possible strings we could create&lt;/em&gt;. You can return the output in &lt;strong&gt;any order&lt;/strong&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: S = &amp;#34;a1b2&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [&amp;#34;a1b2&amp;#34;,&amp;#34;a1B2&amp;#34;,&amp;#34;A1b2&amp;#34;,&amp;#34;A1B2&amp;#34;]
&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: S = &amp;#34;3z4&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [&amp;#34;3z4&amp;#34;,&amp;#34;3Z4&amp;#34;]
&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: S = &amp;#34;12345&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [&amp;#34;12345&amp;#34;]
&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-4"&gt;Example 4
&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: S = &amp;#34;0&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [&amp;#34;0&amp;#34;]
&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;S&lt;/code&gt; will be a string with length between &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;12&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;S&lt;/code&gt; will consist only of letters or digits.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一個字串S，&lt;br&gt;
我們可以任意將其中的單一字母轉換成小寫或大寫，&lt;br&gt;
以創造出另一個字串。&lt;br&gt;
回傳一個列表，當中包含所有我們可以創造出來的字串。&lt;br&gt;
(回傳的字串順序可以不同)&lt;br&gt;
(限制：S的長度會在1~12之間，且S只會有字母或數字)&lt;/p&gt;
&lt;p&gt;這個題目實際上並不是很難想，&lt;br&gt;
從直觀上來說，就是找出所有字母的地方(因為只有字母可以變)，&lt;br&gt;
讓它是小寫或大寫這兩種可能，會產生不一樣的字串，&lt;br&gt;
因此如果當中存在L個字母的話，&lt;br&gt;
其變化就會有2^L種。&lt;/p&gt;
&lt;p&gt;那麼，我們怎麼樣處理這樣子的產生的過程呢？&lt;br&gt;
這就要回頭複習一下回溯法的概念了！&lt;br&gt;
以前我們提到過，回溯法就是當走到一段，無法再往下走時，&lt;br&gt;
回到上一步並還原前面的痕跡，再往下一條路走的做法。&lt;br&gt;
因此，我們來看待這題會變成這樣：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先將整個字串&lt;strong&gt;轉成小寫&lt;/strong&gt; (要都轉成大寫也可以)&lt;/li&gt;
&lt;li&gt;從&lt;strong&gt;index 0&lt;/strong&gt; 開始往下走(將現在的位置定為&lt;strong&gt;pos&lt;/strong&gt; )，&lt;br&gt;
當順著往下走&lt;strong&gt;都不改變&lt;/strong&gt; 時，&lt;br&gt;
最後應該會走到底部，此時&lt;strong&gt;pos == 整個字串長&lt;/strong&gt; ，&lt;br&gt;
這會是&lt;strong&gt;其中一個字串變化，可記錄到結果(res)中&lt;/strong&gt; 。&lt;/li&gt;
&lt;li&gt;接著，回到上一步時，&lt;br&gt;
我們可以&lt;strong&gt;檢查pos位置是否為字母&lt;/strong&gt; ，&lt;br&gt;
&lt;strong&gt;是的話&lt;/strong&gt; ，我們可以&lt;strong&gt;改成將該位置的字母轉為大寫&lt;/strong&gt; ，&lt;br&gt;
再重新往下走一次(因為這樣子變化又不一樣了)&lt;/li&gt;
&lt;li&gt;走到底回到上一層時，&lt;strong&gt;再將字母轉回小寫(回溯法的復原)&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;所以在使用DFS和回溯法時，&lt;br&gt;
讀者請切記兩個要點：&lt;br&gt;
&lt;strong&gt;1. 走到死路(結束時該回頭)的條件要設定好&lt;br&gt;
2. 被更改的東西，在這條路線結束後，記得復原&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;依此，寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分，使用toLowerCase()和toCharArray()，&lt;br&gt;
將字串轉換成&lt;strong&gt;全小寫&lt;/strong&gt; 的字元陣列，方便修改；&lt;br&gt;
我們用helper函數來進行DFS+Backtracking。&lt;br&gt;
在轉換上，使用new String(a)可以從一個字元陣列生成一個字串。&lt;br&gt;
可能&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/a96c8a3c9e1c3ffd013e148d9d61da53.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分，使用&lt;strong&gt;list()&lt;/strong&gt; 來拆成串列，&lt;br&gt;
同時組成字串是使用**’’.join()** 來處理的，&lt;br&gt;
檢查字母是使用&lt;strong&gt;isalpha()&lt;/strong&gt; 函式；&lt;br&gt;
同時請留意**.upper()和.lower()並不直接對原來的東西做修改** ，&lt;br&gt;
而是會&lt;strong&gt;回傳新的str&lt;/strong&gt; ，所以請將其輸入回a[pos]裡，&lt;br&gt;
才會真正修改到。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/1d4f551f6da272348a1edad6d6a61c26.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(2^L)/O(len(S)), L為字串中字母的數量)&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學演算法 - 105 Tree (18) / DFS (15) / Backtracking (7)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-105-tree-18-dfs-15-backtracking-7/</link><pubDate>Mon, 14 Sep 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-105-tree-18-dfs-15-backtracking-7/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 105 Tree (18) / DFS (15) / Backtracking (7)" /&gt;&lt;p&gt;&lt;strong&gt;0437. Path Sum III (Medium)&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;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;You are given a binary tree in which each node contains an integer value.&lt;/p&gt;
&lt;p&gt;Find the number of paths that sum to a given value.&lt;/p&gt;
&lt;p&gt;The path does not need to start or end at the root or a leaf, but it must go downwards (traveling only from parent nodes to child nodes).&lt;/p&gt;
&lt;p&gt;The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000.&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;/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;root = [10,5,-3,3,2,null,11,3,-2,null,1], sum = 8
&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;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; 10
&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 -3
&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; 3 2 11
&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;3 -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;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;Return 3. The paths that sum to 8 are:
&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;/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. 5 -&amp;gt; 3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;2. 5 -&amp;gt; 2 -&amp;gt; 1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;3. -3 -&amp;gt; 11
&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;strong&gt;給定一個二元樹，當中每個節點均含一個整數，&lt;br&gt;
找出所有可以加總等於目標總和的路徑數量。&lt;br&gt;
一個路徑不需要從根節點開始，也不必一定要到葉節點結束，&lt;br&gt;
但是路徑只能往下走(也就是說只能從父節點往子節點走)；&lt;br&gt;
另外，這棵樹最多只會有1000個節點，&lt;br&gt;
且其值均在-1000000~1000000之間。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;這一題是一整組Path Sum系列題的第三題。&lt;br&gt;
由於題目提示節點數不會超過1000個，&lt;br&gt;
所以基本是無法超過各程式的Call Stack限制，可以放心使用遞迴。&lt;/p&gt;
&lt;p&gt;那麼，我們看看另一個重點：&lt;br&gt;
路徑只能往下走，會有什麼特點呢？&lt;br&gt;
舉例來說，以上面的二元樹，當我們走到某個節點2時，&lt;br&gt;
所有終點是2的路徑有以下三種：&lt;br&gt;
10 -&amp;gt; 5 -&amp;gt; 2 &lt;br&gt;
5 -&amp;gt; 2&lt;br&gt;
2&lt;br&gt;
再往下走到1的時候，路徑有以下四種：&lt;br&gt;
&lt;strong&gt;10 -&amp;gt; 5 -&amp;gt; 2&lt;/strong&gt; -&amp;gt; 1&lt;br&gt;
&lt;strong&gt;5 -&amp;gt; 2&lt;/strong&gt; -&amp;gt; 1&lt;br&gt;
&lt;strong&gt;2&lt;/strong&gt; -&amp;gt; 1&lt;br&gt;
1&lt;/p&gt;
&lt;p&gt;我們可以發現，走到1的路徑和到底有沒有符合target的解這件事情，&lt;br&gt;
可以透過兩點知道：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;從root起算走到現在這個節點的總和是否和target相等&lt;/li&gt;
&lt;li&gt;從root起算走到現在這個節點的總和-target是否在過往出現過&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;第2點比較抽象，我們稍微舉一下簡單的例子：&lt;br&gt;
假設我們要找的目標是8的話，&lt;br&gt;
那麼直接看我們當然知道是5-&amp;gt;2-&amp;gt;1，&lt;br&gt;
但如果不能回頭重算的話，要怎麼辦呢？&lt;br&gt;
&lt;strong&gt;我們可以得到5-&amp;gt;2-&amp;gt;1的路徑，&lt;br&gt;
其實相當於從根節點10走到1的路徑和，減去節點10。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;換句話說，如果我們每走到一個節點，都將路徑和記錄下來，&lt;br&gt;
那麼我們就可以用前面過往的路徑和，&lt;br&gt;
來表達出所有達到現在這個節點的路徑和。&lt;/p&gt;
&lt;p&gt;例如：&lt;br&gt;
1其實等於&lt;strong&gt;10 -&amp;gt; 5 -&amp;gt; 2&lt;/strong&gt; -&amp;gt; 1 去掉** 10 -&amp;gt; 5 -&amp;gt; 2&lt;br&gt;
2** -&amp;gt; 1等於** 10 -&amp;gt; 5 -&amp;gt; 2** -&amp;gt; 1去掉** 10 -&amp;gt; 5&lt;br&gt;
5 -&amp;gt; 2** -&amp;gt; 1等於** 10 -&amp;gt; 5 -&amp;gt; 2** -&amp;gt; 1去掉** 10**&lt;/p&gt;
&lt;p&gt;這樣足夠清楚了嗎XD？&lt;br&gt;
因此，我們要做的事情有：&lt;br&gt;
0. 建一個dictionary或hashmap，&lt;br&gt;
當中key/value分別代表路徑和/路徑和出現的次數。&lt;br&gt;
同時，將(0, 1)置入字典當中。(這裡稱之為preSum)&lt;br&gt;
(方便我們在剛好等於根節點到當前節點總長時計算)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;呼叫遞迴DFS函式並回傳其結果。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在DFS函式中，遍歷整棵二元樹：&lt;br&gt;
2.0. 檢查節點是否存在，不存在則回傳0&lt;br&gt;
2.1. 將當前的節點值加上根節點的値，做為現在的總和(currSum)&lt;br&gt;
2.2. 初始化res，其值為currSum-target在preSum中出現的次數&lt;br&gt;
2.3. 分別向左右節點遞迴呼叫DFS函式，將得到的結果加到res&lt;br&gt;
2.4. 由於這條路徑只能一路向下，&lt;br&gt;
所以要回到上一層前，&lt;br&gt;
需將剛剛加過的1次記錄從preSum中扣掉(backtracking)。&lt;br&gt;
2.5. 回傳res&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;依此，寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分preSum使用HashMap，留意先進行一次put，&lt;br&gt;
再放入helper函式中做DFS；&lt;br&gt;
helper函式中的部分，由於HashMap本身找不存在的值會出錯，&lt;br&gt;
別忘了使用getOrDefault來給定預設值(當然，你要用containsKey也行)。&lt;br&gt;
在遞迴取得左右兩邊節點的符合路徑數加總後，&lt;br&gt;
別忘記回傳前要將加上去的刪掉，才符合回溯法的要件。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/5143526b20200b9535b866e51d91a96d.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分大同小異，&lt;br&gt;
不同的是我們可以用defaultdict來將預設值當作0，&lt;br&gt;
從Python的寫法中應該可以更清晰看見回溯法的樣貌。&lt;br&gt;
(先加1後減1)&lt;br&gt;
這邊的helper直接寫成子函式，&lt;br&gt;
所以我們就不需使用self.xxx的形式來呼叫了。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/7e4a95c35aa33ed530333b6371dfcc1b.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;
每個節點最多可以成立d個preSum值，&lt;br&gt;
d為樹的深度，以平衡樹來說則是log(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學演算法 - 104 Tree (17) / DFS (14) / Backtracking (6)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-104-tree-17-dfs-14-backtracking-6/</link><pubDate>Tue, 18 Aug 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-104-tree-17-dfs-14-backtracking-6/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 104 Tree (17) / DFS (14) / Backtracking (6)" /&gt;&lt;p&gt;&lt;strong&gt;0113. Path Sum II (Medium)&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;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a binary tree and a sum, find all root-to-leaf paths where each path’s sum 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 5 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:&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;/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;[
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [5,4,11,2],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [5,8,4,5]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]
&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;分析/解題&lt;br&gt;
給定一個二元樹以及目標的和(sum)，找出所有根節點到葉的路徑，這些路徑各自的和要等於給定的和。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;這一題是一整組Path Sum系列題的第二題。&lt;br&gt;
由於要找出路徑，所以我們需要一組記錄當前路徑current的位置的list。&lt;br&gt;
同時，要能夠判定是否要確認這條路徑OK的狀態，&lt;br&gt;
只取決於現在是否走到葉節點(因為題目要求)；&lt;br&gt;
並且走到葉節點時，左右也都沒有節點了，就無法往下走。&lt;/p&gt;
&lt;p&gt;我們可以用一個result的list記錄最終處理完的結果，&lt;br&gt;
接著使用&lt;strong&gt;DFS&lt;/strong&gt; 的方式往下找。&lt;/p&gt;
&lt;p&gt;那麼自然我們每走過一個節點，&lt;br&gt;
就要將sum減去現在root的値，同時記錄到current上。&lt;/p&gt;
&lt;p&gt;接下來要往下走還是檢查呢？&lt;br&gt;
當然就是看左右節點是否為NIL且sum和root的値是否相等啦！&lt;br&gt;
如果是的話，可以將result加上走到現在的路徑；&lt;br&gt;
如果不是的話，則以DFS往左和往右走(不要忘記去檢查NIL的狀況)。&lt;br&gt;
這整段走完要回到上一層的時候，表示已經處理完了，&lt;br&gt;
&lt;strong&gt;不要忘記我們先前將這層root的値放進了current裡面，&lt;br&gt;
所以我們應該要將其移除。&lt;/strong&gt;(** Backtracking**的部分)&lt;/p&gt;
&lt;p&gt;依此，寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分我們可以使用同名但不同參數長度的函式，&lt;br&gt;
直接利用開頭檢查root，&lt;br&gt;
來順便處理後續帶入root.left/root.right所需要的檢查。&lt;br&gt;
Backtracking的部分，&lt;br&gt;
currentResult先加上root.val後，後續再進行remove即可；&lt;br&gt;
而留意由於我們不斷地在變換currentResult，&lt;br&gt;
不要忘記要將其複製一份以加到result裡面，而非直接用加的。&lt;br&gt;
(使用&lt;strong&gt;new LinkedList(currentResult)&lt;/strong&gt; )&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/6d08f8daf783bd267da27465c43c98fe.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;同理，Python的部分一樣需要複製，&lt;br&gt;
我們可以寫成curr[:]以複製一份用來讓res進行附加。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/384a6f215dc4c816f3bbdb93edbe8fb8.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N)/O(logN)，因為整棵樹要遍歷過一遍，&lt;br&gt;
然後平均而言，樹的深度會到O(logN)，&lt;br&gt;
所以空間複雜度所以空間複雜度，這個部分不包含result的占用空間)&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學演算法 - 81 Backtracking (5) / DFS (7)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-81-backtracking-5-dfs-7/</link><pubDate>Tue, 07 Jan 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-81-backtracking-5-dfs-7/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 81 Backtracking (5) / DFS (7)" /&gt;&lt;p&gt;&lt;strong&gt;0093. Restore IP Addresses (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a string containing only digits, restore it by returning all possible valid IP address combinations.&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;/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: &amp;#34;25525511135&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [&amp;#34;255.255.11.135&amp;#34;, &amp;#34;255.255.111.35&amp;#34;]
&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;給定一個僅含數字0~9的字串，將其還原成所有合法的IP位址的可能組合。&lt;/p&gt;
&lt;p&gt;對於IP而言，我們所需考慮的有以下幾個條件：&lt;br&gt;
&lt;strong&gt;1. 共分4段(且必須恰好是4段)&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;2. 中間以小數點連接，每組的數字在0~255之間&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果定義再清楚一點的話，&lt;br&gt;
可以補上前面寫0的部分除了0以外不能納入，會更好一點。&lt;br&gt;
(比如113.002.22.3不會是合法的IP，但一個IP可以是0.0.0.0)&lt;/p&gt;
&lt;p&gt;所以這題也是很典型的&lt;strong&gt;Backtracking+DFS&lt;/strong&gt; 的題目：&lt;br&gt;
&lt;strong&gt;每次從s上面按順序取一段長度，檢查它是否合法，&lt;br&gt;
再遞迴取下一段。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;那麼，我們需要考慮一些邊界的條件，&lt;br&gt;
以便於我們考慮什麼時候該「回頭」：&lt;br&gt;
最基本的條件，就是&lt;strong&gt;已經分到第4段&lt;/strong&gt; 了，&lt;br&gt;
我們應該要考慮這段剩下的部分是否合法。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;當剩下的長度&amp;gt;3&lt;/strong&gt; =&amp;gt; 根本就超過了，完全不用考慮XD&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;剩下的長度≤3且轉成數字≤255&lt;/strong&gt; ，即可將該段補齊並加到結果。&lt;br&gt;
例外：連續的0會有問題，所以要優先檢查是否&lt;strong&gt;剛好為'0&amp;rsquo;&lt;/strong&gt; 的狀況，&lt;br&gt;
&lt;strong&gt;除了剛好為&amp;quot;0&amp;quot;的狀況外，首字元為'0&amp;rsquo;就必須被排除掉&lt;/strong&gt; 。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;邊界條件考慮完後，我們來考慮一般的分段法。&lt;/p&gt;
&lt;p&gt;在開始之前，可以&lt;strong&gt;先排除掉剩下的長度小於所需的分段數&lt;/strong&gt; 的狀況，&lt;br&gt;
用以避免取分段時超出邊界。&lt;br&gt;
(例如剩下長度為2，但還需要取3段，那麼顯然不夠用)&lt;/p&gt;
&lt;p&gt;假設現在我們接下來要取的位置在 &lt;strong&gt;i&lt;/strong&gt; ，要取 &lt;strong&gt;j&lt;/strong&gt; 個字元：&lt;br&gt;
那麼 &lt;strong&gt;j可以是1~3，但 i+j 不能超過s的長度&lt;/strong&gt; 。&lt;br&gt;
我們會發現&lt;strong&gt;額外要考慮的就是上面的2的部分&lt;/strong&gt; ，&lt;br&gt;
取完一段以後，呼叫相同的函式進行遞迴，&lt;br&gt;
不要忘記除了上一次傳進來的&lt;strong&gt;前導字串cur&lt;/strong&gt; 外，&lt;br&gt;
要加上的是&lt;strong&gt;這次取的分段&lt;/strong&gt; ，以及&lt;strong&gt;分隔用的小數點&amp;quot;.&amp;quot;&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;依此，寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分，我們使用LinkedList來記錄結果res，&lt;br&gt;
傳入的參數有該字串s，res，當前要取的索引值i，&lt;br&gt;
當前的分段cnt(從0起算)，以及到目前為止的IP的字串cur。&lt;br&gt;
由於每次呼叫checkIP時帶進去的字串都是&lt;strong&gt;新生成&lt;/strong&gt; 的，&lt;br&gt;
所以回到上一層時就自然還原了cur的狀態，&lt;br&gt;
不用像之前的棋盤搜尋字串問題中需要額外考慮要還原的問題。&lt;br&gt;
&lt;strong&gt;每次開始前不要忘記檢查s.length()-i &amp;lt; 4 - cnt的邊界&lt;/strong&gt; ，&lt;br&gt;
若已經不符則可直接return。&lt;br&gt;
&lt;strong&gt;(註：理論上也可以額外檢查s.length()-i &amp;gt; (4-cnt)*4的邊界，&lt;br&gt;
但實測上並不會因此變快，推估可能理由和檢查255的問題一樣)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;另外請務必留意在比較字串是否相等時&lt;strong&gt;請使用equals()的函式&lt;/strong&gt; ，&lt;br&gt;
&lt;strong&gt;不要使用&amp;quot;==&amp;quot;(會出錯)&lt;/strong&gt; 。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/1ae57afd061a562a0eab62b379fed9b4.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分也是一樣的概念，&lt;br&gt;
只是substring的操作可以簡單用&lt;strong&gt;s[i:j]&lt;/strong&gt; 的形式來處理，&lt;br&gt;
且比較相等可以直接使用&amp;quot;==&amp;quot;。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/8c7e831c5468b6b48e5334890e3613fb.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(len(s)) / O(len(s))，更廣義來說，其實&lt;strong&gt;長度必須在12&lt;/strong&gt; 以內，&lt;br&gt;
所以&lt;strong&gt;最大的佔用空間和時間是可以固定的&lt;/strong&gt; ，&lt;br&gt;
要說O(1)也不太算有錯就是了。)&lt;/p&gt;
&lt;p&gt;「為什麼不是當3位數才檢查小於等於255？」&lt;br&gt;
(這樣必須要先分開3位數及其他，變成要先經過另一組判斷式，&lt;br&gt;
整體而言不會比較節省時間。)&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;/p&gt;
&lt;p&gt;筆者開設的系列同名線上課程：&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜基礎篇」已經上線啦！&lt;/strong&gt; 在這堂課中，你將學會利用十種演算法/資料結構來優化解題過程，&lt;br&gt;
並實際完整練習&lt;strong&gt;20題&lt;/strong&gt; 精選考古題，&lt;br&gt;
進而逐漸提升到不需提示也可以突破白板題，取得工作門票！&lt;br&gt;
&lt;strong&gt;Medium優惠(最後一波早鳥優惠了，不確定調回原價是什麼時候)：&lt;/strong&gt; &lt;a class="link" href="https://hiskio.com/courses/319?promo_code=VEQZV7E" target="_blank" rel="noopener"
&gt;** https://hiskio.com/courses/319?promo_code=VEQZV7E**&lt;/a&gt;&lt;/p&gt;</description></item><item><title>從LeetCode學演算法 - 63 Backtracking (4) / DFS (6)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-63-backtracking-4-dfs-6/</link><pubDate>Fri, 18 Oct 2019 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-63-backtracking-4-dfs-6/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 63 Backtracking (4) / DFS (6)" /&gt;&lt;p&gt;&lt;strong&gt;0077. Combinations (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given two integers &lt;em&gt;n&lt;/em&gt; and &lt;em&gt;k&lt;/em&gt;, return all possible combinations of &lt;em&gt;k&lt;/em&gt; numbers out of 1 … &lt;em&gt;n&lt;/em&gt;.&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;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;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; 8
&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; 9
&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;10
&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: n = 4, k = 2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output:
&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,4],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [3,4],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [2,3],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [1,2],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [1,3],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [1,4],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]
&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;給定兩個整數n跟k，回傳所有1~n之間取k個數字的組合。&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-60-backtracking-3-dfs-5-ccc679dfa407" target="_blank" rel="noopener"
&gt;0078. Subsets&lt;/a&gt;非常的接近，&lt;br&gt;
差別在於我們必須改成取得&lt;strong&gt;固定k個&lt;/strong&gt; ，&lt;br&gt;
所以現在考慮上必須要將**「目前將取到第幾個數字」** 這件事情納入考量。&lt;/p&gt;
&lt;p&gt;那麼，我們可以同樣用&lt;strong&gt;backtracking(回溯法)&lt;/strong&gt; 的方式來考慮。&lt;br&gt;
我們考慮初始化一個組合&lt;strong&gt;combo&lt;/strong&gt; ，從&lt;strong&gt;1&lt;/strong&gt; 開始決定要不要加入組合中，&lt;br&gt;
&lt;strong&gt;並記錄現在走到的index(以i表示)&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;那麼，我們需要傳入的參數值有：&lt;br&gt;
&lt;strong&gt;combo&lt;/strong&gt; (當前未完成的組合), &lt;strong&gt;res&lt;/strong&gt; (記錄結果的所有已完成的組合),&lt;br&gt;
&lt;strong&gt;n&lt;/strong&gt; (1~n的數字), k(&lt;strong&gt;連同當前這輪，還有幾個數字要被納入組合&lt;/strong&gt; ),&lt;br&gt;
&lt;strong&gt;i&lt;/strong&gt; (當前走到的數字)&lt;/p&gt;
&lt;p&gt;那麼，我們可以使用遞迴(命名為findCombos)來處理這題，&lt;br&gt;
當&lt;strong&gt;k等於0&lt;/strong&gt; 時，表示&lt;strong&gt;已經完成這個組合，將其加入res中&lt;/strong&gt; ；&lt;br&gt;
否則當&lt;strong&gt;i ≤ n&lt;/strong&gt; 時，表示還有** 可以選擇的數字**(** 且組合還沒完成**)，&lt;br&gt;
此時可以分成 &lt;strong&gt;a.&lt;/strong&gt; ** 將i加入combo 或 b. 不加入combo** 中。&lt;br&gt;
&lt;strong&gt;a. 將i加入combo中的話&lt;/strong&gt; -&amp;gt; ** 代入findCombos的遞迴中k要減1，i要加1。&lt;br&gt;
且這輪下去遞迴完以後，記得將狀態復原(把combo的最後一個數字拿掉)&lt;br&gt;
b. 不將i加入combo的話** -&amp;gt; 代入findCombos的遞迴僅需i要加1即可。&lt;br&gt;
(因為只有當前選擇的數字增加)&lt;/p&gt;
&lt;p&gt;除此以外，我們可以額外考慮一件事情：&lt;br&gt;
由於&lt;strong&gt;剩下的可選數字應該大於我們還需要選擇的數字&lt;/strong&gt; ，&lt;br&gt;
所以 &lt;strong&gt;i≤n&lt;/strong&gt; 的條件應該可以進一步縮限成 ** i+k-1 ≤ n**。&lt;/p&gt;
&lt;p&gt;依此，寫成如下的程式碼。&lt;/p&gt;
&lt;p&gt;Java的部分，可以使用ArrayList/LinkedList皆可，&lt;br&gt;
並且保險起見，可以先行檢查n和k。&lt;br&gt;
(畢竟測資也有可能弄個不合法的負數或零)&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/49e8608b732ca7e4e5c5a8cb97bbf041.js"&gt;&lt;/script&gt;
&lt;p&gt;如之前的文章，Python請不要忘記append到combo上的必須是複製的list。&lt;br&gt;
此外也可以使用itertools的combination來直接得到答案，&lt;br&gt;
但&lt;strong&gt;請不要&lt;/strong&gt; 在面試的時候這樣用XD&lt;br&gt;
(因為這只證明了你知道工具，而不是你懂回溯法)&lt;/p&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/9b53e51c03b38e361cd20bf7f3523a40.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(C(n, k))/O(k*C(n,k))。&lt;br&gt;
由於k的値會影響階乘連接的個數，所以不好化簡。)&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><item><title>從LeetCode學演算法 - 60 Backtracking (3) / DFS (5)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-60-backtracking-3-dfs-5/</link><pubDate>Mon, 07 Oct 2019 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-60-backtracking-3-dfs-5/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 60 Backtracking (3) / DFS (5)" /&gt;&lt;p&gt;&lt;strong&gt;0078. Subsets (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;(當然，Medium的拍手也可以多拍幾下啦XD)&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a set of &lt;strong&gt;distinct&lt;/strong&gt; integers, &lt;em&gt;nums&lt;/em&gt;, return all possible subsets (the power set).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The solution set must not contain duplicate subsets.&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;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;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; 8
&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; 9
&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;10
&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;11
&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;12
&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: nums = [1,2,3]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output:
&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; [3],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [1],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [2],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [1,2,3],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [1,3],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [2,3],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [1,2],
&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;]
&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;給定一組內含相異的整數的集合nums，試回傳其power set。&lt;br&gt;
(所有可能的子集合，包含空集合)&lt;/p&gt;
&lt;p&gt;我們先考慮一下所謂的子集合。&lt;br&gt;
所謂的子集合就是在指說，在nums所有的元素(element)中，&lt;br&gt;
有哪些要被用，哪些不要被用的所有組合。&lt;br&gt;
所以對於每個數都有加進去/不加進去的兩種可能，&lt;br&gt;
如果nums有N個元素，所有的組合的可能是就會是2^N。&lt;/p&gt;
&lt;p&gt;我們可以透過上述的思路來建構遞迴的函式。&lt;br&gt;
首先，我們先產生一個subset，&lt;br&gt;
用來&lt;strong&gt;存放走到當前的狀況&lt;/strong&gt; ，&lt;br&gt;
&lt;strong&gt;而一個確定可以放進結果res的subset，&lt;br&gt;
必須是將整個nums走完且決定誰要進，誰不要進才行。&lt;/strong&gt;&lt;br&gt;
要放進subset和不放都是可行的選擇，&lt;br&gt;
那麼我們就必須要&lt;strong&gt;分岔成兩條路&lt;/strong&gt; ：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;將當前遇到的數字置之不理，&lt;strong&gt;直接朝向下一個index走&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;先將當前遇到的數字加進subset中&lt;/strong&gt; ，再朝下一個index走&lt;br&gt;
留意當&lt;strong&gt;回到上一層&lt;/strong&gt; 的時候，這個index遇到的數字同樣&lt;strong&gt;應該要被取消掉&lt;/strong&gt; ，&lt;br&gt;
所以我們應該要&lt;strong&gt;從subset中拔掉最後一個數字&lt;/strong&gt; 。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;那麼&lt;strong&gt;遞迴的尾端&lt;/strong&gt; ，自然就是當index&lt;strong&gt;走超過範圍&lt;/strong&gt; 的時候，&lt;br&gt;
此時我們應該&lt;strong&gt;將這個subset作為其中一個結果放入到res中，&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;並回到上一層。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;依此，我們可以寫成如下的程式碼。&lt;br&gt;
在Java的部分，List使用LinkedList或ArrayList皆可，&lt;br&gt;
ArrayList適用於需要取得某個點的値，&lt;br&gt;
而LinkedList在儲存時會稍微快一點，&lt;br&gt;
請留意我們在新增組合時是使用&lt;strong&gt;new ArrayList&amp;lt;&amp;gt;(subset)&lt;/strong&gt; ，&lt;br&gt;
用以加入subset的複本來放入res中。&lt;br&gt;
&lt;strong&gt;如果單純放subset的話，由於大家都指向相同的位置，&lt;br&gt;
後面修改subset的時候會導致res內的內容也同部被改到，&lt;br&gt;
請務必留意XD&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/471ea22f9965dac78c83ae46a3bd0496.js"&gt;&lt;/script&gt;
&lt;p&gt;這邊也提供了參考的其它解，包含了迭代解和另一種遞迴解，&lt;br&gt;
概念都是**拿現在的所有組合和新的數字，決定要加或不要加，&lt;br&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-11-bitwise-operation-1-3117c4ce925d" target="_blank" rel="noopener"
&gt;Gray Code&lt;/a&gt;的解法，&lt;br&gt;
用原先的部分來組新的東西，有興趣可再參考。&lt;/p&gt;
&lt;p&gt;Python的部分一樣需注意subset要使用copy來複製一份使用。&lt;/p&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/12f4afa1f169926a36e33f031860c7e1.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(2^N)/O(2^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;</description></item><item><title>從LeetCode學演算法 - 59 Backtracking (2) / DFS (4)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-59-backtracking-2-dfs-4/</link><pubDate>Fri, 04 Oct 2019 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-59-backtracking-2-dfs-4/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 59 Backtracking (2) / DFS (4)" /&gt;&lt;p&gt;&lt;strong&gt;0079. Word Search (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;(當然，Medium的拍手也可以多拍幾下啦XD)&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a 2D board and a word, find if the word exists in the grid.&lt;/p&gt;
&lt;p&gt;The word can be constructed from letters of a sequentially adjacent cell, where “adjacent” cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.&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;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;/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;board =
&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; [&amp;#39;A&amp;#39;,&amp;#39;B&amp;#39;,&amp;#39;C&amp;#39;,&amp;#39;E&amp;#39;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&amp;#39;S&amp;#39;,&amp;#39;F&amp;#39;,&amp;#39;C&amp;#39;,&amp;#39;S&amp;#39;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [&amp;#39;A&amp;#39;,&amp;#39;D&amp;#39;,&amp;#39;E&amp;#39;,&amp;#39;E&amp;#39;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]
&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;/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;Given word = &amp;#34;ABCCED&amp;#34;, return true.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Given word = &amp;#34;SEE&amp;#34;, return true.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Given word = &amp;#34;ABCB&amp;#34;, return false.
&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;給定一個2維棋盤和一個字(word)，檢查這個字是否存在這個棋盤裡。&lt;br&gt;
構成字的方式是從棋盤的某一格開始，連續選取相鄰的格子。&lt;br&gt;
同時，相同的格子不能使用兩次。&lt;/p&gt;
&lt;p&gt;前面提到過Backtracking(回溯法)，&lt;br&gt;
這題同樣也是典型的DFS+Backtracking方法可以處理的對象。&lt;/p&gt;
&lt;p&gt;首先，要構成一個字，就要從&lt;strong&gt;棋盤上選擇一個位置開始往下&lt;/strong&gt; 。&lt;br&gt;
每次選一個相鄰的格子，拿來跟word比對，&lt;br&gt;
都必須要和word對應的位置上的字元(char)相同才行，&lt;br&gt;
所以這表示我們還要&lt;strong&gt;記錄現在比對到哪個index&lt;/strong&gt; 了。&lt;br&gt;
同時，由於用過的格子不能重複使用，每次在進入dfs的時候，&lt;br&gt;
我們必須要&lt;strong&gt;記錄是否有造訪(visit)過這個格子&lt;/strong&gt; ，&lt;br&gt;
才往更深處呼叫；同時，在該層的&lt;strong&gt;四個方向都判斷完以後&lt;/strong&gt; ，&lt;br&gt;
&lt;strong&gt;回到上一層之前，必須將造訪的紀錄還原回去&lt;/strong&gt; 。&lt;br&gt;
(因為我們只有在這次走這條路的時候有造訪，&lt;br&gt;
回到上一層的時候這個格子應該處於沒有造訪過的狀態)&lt;/p&gt;
&lt;p&gt;所以最開始我們要做的事情是，&lt;br&gt;
&lt;strong&gt;使用迴圈分別將每個cell作為起始點，開始進行搜尋。&lt;br&gt;
(搜尋的遞迴函式如果其中一次是True的話就可以直接回傳True)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;每次搜尋的時候，傳入的有：&lt;br&gt;
&lt;strong&gt;board(棋盤), r, c(當前的cell位置), &lt;br&gt;
index(比對到word的哪一個char), word&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;每一次我們要做的步驟：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;檢查board[r][c]和word的index處的值是否不同&lt;/strong&gt; ，&lt;br&gt;
&lt;strong&gt;不同則回傳False&lt;/strong&gt; 表示這條路行不通。&lt;/li&gt;
&lt;li&gt;檢查&lt;strong&gt;index&lt;/strong&gt; 是否已經走到最後了(&lt;strong&gt;length of word - 1&lt;/strong&gt; )，&lt;br&gt;
是的話代表&lt;strong&gt;這條路到這邊剛好就是答案，回傳True&lt;/strong&gt; 。&lt;/li&gt;
&lt;li&gt;將&lt;strong&gt;index遞增&lt;/strong&gt; (接下來要給下面遞迴使用)，並&lt;strong&gt;將board[r][c]標明已造訪&lt;/strong&gt; 。&lt;/li&gt;
&lt;li&gt;分別以往&lt;strong&gt;上下左右&lt;/strong&gt; 方向的&lt;strong&gt;新的(r, c)值來代入函式進行遞迴搜尋&lt;/strong&gt; ，&lt;br&gt;
&lt;strong&gt;如果結果是True的話，直接回傳True&lt;/strong&gt; 。(也就是下面的部份都不用做了XD)&lt;br&gt;
(這邊記得要&lt;strong&gt;檢查上下左右移動一格以後是否超出board範圍&lt;/strong&gt; )&lt;/li&gt;
&lt;li&gt;前面四個都是False的狀況，代表這條路行不通了，&lt;br&gt;
我們要回到上一步，這時候要&lt;strong&gt;先將board[r][c]標明未造訪&lt;/strong&gt; ，&lt;br&gt;
才&lt;strong&gt;回傳False&lt;/strong&gt; 。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果跑完整個棋盤，都沒有能夠成立的路徑的話，&lt;br&gt;
就應該&lt;strong&gt;回傳False&lt;/strong&gt; 作為答案。(因為我們沒有找到可行的路徑)&lt;/p&gt;
&lt;p&gt;在實作時為了方便起見，我們可以宣告class的變數來放一些常用的東西，&lt;br&gt;
這邊用了wlen(word的長度), row, col(board的列/行數)。&lt;br&gt;
需要注意的是，在實作造訪與否的紀錄時，&lt;br&gt;
我們可以選擇使用像是visited[][]的二維陣列來寫，&lt;br&gt;
但也可以採用別的方法，比如將裡面的值暫時設為&amp;quot;0&amp;quot;，&lt;br&gt;
後面再還原，或者像Java這邊寫的將其&lt;strong&gt;和128進行XOR&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;為什麼和128進行XOR呢？&lt;br&gt;
因為&lt;a class="link" href="https://zh.wikipedia.org/zh-tw/ASCII" target="_blank" rel="noopener"
&gt;ASCII&lt;/a&gt;中的所有字元值均不超過128，&lt;br&gt;
也就是說，它們在&lt;strong&gt;二進位上的第8位數(由右數到左)均為0&lt;/strong&gt; 。&lt;br&gt;
XOR後，第8位數會變成1，所以再度遞迴下去比對時，&lt;br&gt;
就不可能等於任何字元，從而達到標示造訪過的目的。&lt;/p&gt;
&lt;p&gt;還原回來的時候，因為：&lt;br&gt;
a XOR 128 XOR 128 ＝ a XOR 0 = a&lt;br&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-15-bitwise-operation-2-b3084a69698f" target="_blank" rel="noopener"
&gt;&lt;strong&gt;先前的文章&lt;/strong&gt; &lt;/a&gt;有提到過的Bitwise Operation)&lt;/p&gt;
&lt;p&gt;所以&lt;strong&gt;再重複用128進行一次XOR即可還原原先的值&lt;/strong&gt; 了！&lt;/p&gt;
&lt;p&gt;寫成程式碼如下：&lt;br&gt;
(留意Java可以&lt;strong&gt;直接對char當作是數字來操作&lt;/strong&gt; )&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/ecf56cb50c83a8b2f953cb8ec92dce67.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/168bc64792811dd2546e07934435de3e.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(如果row = m, col = n，word長度=l的話，從每個點出發一次，&lt;br&gt;
並且每次都有4個方向的選擇(但只有三個方向能繼續延伸)，&lt;br&gt;
時間複雜度會是O(m * n * 3^L)。&lt;br&gt;
空間複雜度的部分，如果考慮call stack的話，最大會是O(L)，&lt;br&gt;
不考慮的話，由於沒有使用visited[][]來處理，則會是O(1)。&lt;br&gt;
如果用visited來存放的話則是O(m*n))&lt;/p&gt;
&lt;p&gt;「在Python中是否可以使用類似Java對char的解法來處理呢？」&lt;br&gt;
(可以，請使用ord()將單個字元進行轉換成數字再進行xor，&lt;br&gt;
不能直接用str型態的値來處理。)&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;
Raiy Kuo: 細算的話選擇方向這部份的時間複雜度是3^L，&lt;br&gt;
詳情請見response中的討論。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;(歡迎提供意見協助更正歐~)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;從LeetCode學演算法，我們下次見囉，掰~&lt;/p&gt;</description></item><item><title>從LeetCode學演算法 - 42 Backtracking (1) / Tree (8)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-42-backtracking-1-tree-8/</link><pubDate>Thu, 29 Aug 2019 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-42-backtracking-1-tree-8/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 42 Backtracking (1) / Tree (8)" /&gt;&lt;p&gt;&lt;strong&gt;0257. Binary Tree Paths (Easy)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a binary tree, return all root-to-leaf paths.&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;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:
&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
&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
&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
&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;/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: [&amp;#34;1-&amp;gt;2-&amp;gt;5&amp;#34;, &amp;#34;1-&amp;gt;3&amp;#34;]
&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;/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;Explanation: All root-to-leaf paths are: 1-&amp;gt;2-&amp;gt;5, 1-&amp;gt;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="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一個二元樹，回傳其所有根到葉的路徑。&lt;br&gt;
這題是Easy難度的題目，剛好藉由它來講一下&lt;strong&gt;回溯法(Backtracking)&lt;/strong&gt; 。&lt;br&gt;
這個題目看起來挺簡單的，如果沒有特別要求的話，寫起來也不難，&lt;br&gt;
依照遞回的模式就可以順利解決，&lt;br&gt;
思路大致上是&lt;strong&gt;每走一步就將root的值串上path字串&lt;/strong&gt; ，&lt;br&gt;
直到左右均無節點，表示已走到葉節點了，即可將其放到結果res中。&lt;/p&gt;
&lt;p&gt;所以一般可能會寫成這樣：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-42-backtracking-1-tree-8/image-001.png"
width="554"
height="323"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-42-backtracking-1-tree-8/image-001_hu_81768293eb260095.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-42-backtracking-1-tree-8/image-001_hu_311c8f185488e9e3.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="171"
data-flex-basis="411px"
&gt;&lt;/p&gt;
&lt;p&gt;可以通過但不盡理想的遞回解&lt;/p&gt;
&lt;p&gt;這麼做其實不盡理想，&lt;br&gt;
因為我們會發現裡面的&lt;strong&gt;每一個tmp其實都是使用一個新的變數&lt;/strong&gt; ，&lt;br&gt;
顯然這件事情會讓我們花費更多的空間(因為產生新的變數)。&lt;br&gt;
怎麼辦呢？這時候就到了回溯法上場的時候了。&lt;/p&gt;
&lt;p&gt;我們之前有介紹過&lt;strong&gt;DFS/BFS&lt;/strong&gt; ，&lt;br&gt;
分別代表著&lt;strong&gt;深度優先搜尋&lt;/strong&gt; 和&lt;strong&gt;廣度優先搜尋&lt;/strong&gt; ，&lt;br&gt;
如這題前面的解法其實也可以當作DFS來看待，&lt;/p&gt;
&lt;p&gt;而&lt;strong&gt;回溯法的概念又更廣泛一些&lt;/strong&gt; ：&lt;br&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;br&gt;
則&lt;strong&gt;回復到上一個階段&lt;/strong&gt; 的搜尋，並&lt;strong&gt;取消&lt;/strong&gt; 掉這個階段所造成的影響。&lt;br&gt;
(過程中視要求，可在找到所有答案後才回傳，或者找到第一個答案就回傳)&lt;/p&gt;
&lt;p&gt;簡單來說，就是&lt;strong&gt;一個一個試，&lt;br&gt;
走錯了就回頭&lt;/strong&gt;，而且記得先前** 試的痕跡要處理掉**就對了XD&lt;br&gt;
聽起來可能還是有點抽象，我們講這題的實作方式好了。&lt;/p&gt;
&lt;p&gt;要進行回溯法，首先要&lt;strong&gt;確立要處理的對象&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;例如這題裡面最重要的是&lt;strong&gt;節點經過的路徑&lt;/strong&gt; ，&lt;br&gt;
那麼我們應該可以將當前的路徑當作主要處理的對象：&lt;br&gt;
每次在遞迴函式中應該要做的事情有：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;將當前的&lt;strong&gt;根節點&lt;/strong&gt; 加到&lt;strong&gt;路徑&lt;/strong&gt; 的ArrayList中&lt;/li&gt;
&lt;li&gt;如果&lt;strong&gt;左節點&lt;/strong&gt; 存在，遞迴進行&lt;strong&gt;左子樹&lt;/strong&gt; 的部分&lt;/li&gt;
&lt;li&gt;如果&lt;strong&gt;右節點&lt;/strong&gt; 存在，遞迴進行&lt;strong&gt;右子樹&lt;/strong&gt; 的部分&lt;/li&gt;
&lt;li&gt;如果&lt;strong&gt;左右節點均不存在&lt;/strong&gt; ，表示&lt;strong&gt;該路徑是答案要求的其中一條&lt;/strong&gt; ，&lt;br&gt;
將整個路徑內的節點值按照要求的格式&lt;strong&gt;輸出到結果res中&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;走完前4步，&lt;strong&gt;這個階段的可能性均搜索完畢&lt;/strong&gt; ，&lt;br&gt;
所以要回到上一個階段，這時&lt;strong&gt;在1.的時候加入的根節點應該要被移除&lt;/strong&gt; ，&lt;br&gt;
因為上一個階段並沒有它。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;可以看到在回溯法中，路徑的部分是&lt;strong&gt;所有函式共用&lt;/strong&gt; 的，&lt;br&gt;
所以只要妥善處理用完後復原，即可使用一個List來處理整個樹的狀況，&lt;br&gt;
這個List最大的占用空間就是&lt;strong&gt;這棵樹的深度&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;依此，我們可以寫出其程式碼。&lt;/p&gt;
&lt;p&gt;Java的部分，這邊用DFS來命名遞迴的函式名，&lt;br&gt;
也可以叫getPath，可依讀者喜號命名。&lt;br&gt;
使用StringBuilder來進行字串的整理(加上”-&amp;gt;”)，&lt;br&gt;
以及使用ArrayList/LinkedList來處理path相關的部分。&lt;br&gt;
(應該是用哪個都可以啦XD 題目只限定List)&lt;br&gt;
最後不要忘記每次該階段做完要將最後一個進行移除(remove)。&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/2e94391aaf8a2a5f54b587813db51366.js"&gt;&lt;/script&gt;
&lt;p&gt;Python的部份我們可以直接使用List來處理，&lt;br&gt;
並且利用&lt;strong&gt;join&lt;/strong&gt; 的特性可以很方便地串接所有的path。&lt;br&gt;
最後一樣不要忘記移除當階段的痕跡(&lt;strong&gt;pop&lt;/strong&gt; )。&lt;/p&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/f6098638545b957af09e4e7432330adc.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(時間複雜度為O(N)(因為要掃過整棵樹)；&lt;br&gt;
空間複雜度的部分，使用的path在平衡的狀態下複雜度是O(logN)&lt;br&gt;
而最後的res部分如果用個數來看的話，完美的二元樹深度是O(logN)，&lt;br&gt;
路徑數是O(N)，所以總占用空間是O(N * logN) )&lt;/p&gt;
&lt;h2 id="相似及延伸"&gt;相似及延伸
&lt;/h2&gt;&lt;p&gt;1.&lt;a class="link" href="https://leetcode.com/problems/path-sum-ii/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;0113. Path Sum II&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></channel></rss>