<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>DFS on 跟著 Desolve 學程式</title><link>https://desolve.pages.dev/tags/dfs/</link><description>Recent content in DFS on 跟著 Desolve 學程式</description><generator>Hugo -- gohugo.io</generator><language>zh-tw</language><lastBuildDate>Wed, 01 May 2024 00:00:00 +0800</lastBuildDate><atom:link href="https://desolve.pages.dev/tags/dfs/index.xml" rel="self" type="application/rss+xml"/><item><title>Learn Algorithms from LeetCode-121 (0802. Find Eventual Safe States)</title><link>https://desolve.pages.dev/post/learn-algorithms-from-leetcode-121-0802-find-eventual-safe-states/</link><pubDate>Wed, 01 May 2024 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithms-from-leetcode-121-0802-find-eventual-safe-states/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post Learn Algorithms from LeetCode-121 (0802. Find Eventual Safe States)" /&gt;&lt;h2 id="categories-graphdfs"&gt;Categories: Graph/DFS
&lt;/h2&gt;&lt;h2 id="level-medium"&gt;Level: Medium
&lt;/h2&gt;&lt;p&gt;Introduction: (Basic + Advanced + Interview Edition) &lt;br&gt;
Learning Algorithms from LeetCode + Interview Success Guide &lt;br&gt;
(Regular price: 3591 NTD, Discounted price until 2024/05/16 23:59)&lt;br&gt;
&lt;a class="link" href="https://hiskio.com/bundles/egb397?s=tc" target="_blank" rel="noopener"
&gt;https://hiskio.com/bundles/egb397?s=tc&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;(Regular price: 3990 NTD, Valid for a long term) &lt;br&gt;
&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;Please help me click on the “SHOW EMBED” below and give it 5 likes~ If you like it, you can also give me a round of applause~ &lt;br&gt;
(Liking doesn’t cost anything, thank you for supporting my writing~)&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;There is a directed graph of &lt;code&gt;n&lt;/code&gt; nodes with each node labeled from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;n - 1&lt;/code&gt;. The graph is represented by a &lt;strong&gt;0-indexed&lt;/strong&gt; 2D integer array &lt;code&gt;graph&lt;/code&gt; where &lt;code&gt;graph[i]&lt;/code&gt; is an integer array of nodes adjacent to node &lt;code&gt;i&lt;/code&gt;, meaning there is an edge from node &lt;code&gt;i&lt;/code&gt; to each node in &lt;code&gt;graph[i]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A node is a &lt;strong&gt;terminal node&lt;/strong&gt; if there are no outgoing edges. A node is a ** safe node** if every possible path starting from that node leads to a ** terminal node** (or another safe node).&lt;/p&gt;
&lt;p&gt;Return &lt;em&gt;an array containing all the&lt;/em&gt; *&lt;strong&gt;safe nodes&lt;/strong&gt; * &lt;em&gt;of the graph&lt;/em&gt;. The answer should be sorted in &lt;strong&gt;ascending&lt;/strong&gt; order.&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-algorithms-from-leetcode-121-0802-find-eventual-safe-states/image-001.png"
width="800"
height="228"
srcset="https://desolve.pages.dev/post/learn-algorithms-from-leetcode-121-0802-find-eventual-safe-states/image-001_hu_a8658ffdefe37f65.png 480w, https://desolve.pages.dev/post/learn-algorithms-from-leetcode-121-0802-find-eventual-safe-states/image-001_hu_43b3ee2d7a89e4a5.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="350"
data-flex-basis="842px"
&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;/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: graph = [[1,2],[2,3],[5],[0],[5],[],[]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [2,4,5,6]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: The given graph is shown above.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Nodes 5 and 6 are terminal nodes as there are no outgoing edges from either of them.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Every path starting at nodes 2, 4, 5, and 6 all lead to either node 5 or 6.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-2"&gt;Example 2
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: graph = [[1,2,3,4],[1,2],[3,4],[0,4],[]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [4]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation:
&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 == graph.length&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1 &amp;lt;= n &amp;lt;= 104&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0 &amp;lt;= graph[i].length &amp;lt;= n&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0 &amp;lt;= graph[i][j] &amp;lt;= n - 1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;graph[i]&lt;/code&gt; is sorted in a strictly increasing order.&lt;/li&gt;
&lt;li&gt;The graph may contain self-loops.&lt;/li&gt;
&lt;li&gt;The number of edges in the graph will be in the range &lt;code&gt;[1, 4 * 104]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Analysis/Approach:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There is a directed graph with n nodes, each labeled from 0 to n-1. The graph is represented using a 2D array called “graph,” where graph[i] represents the nodes connected to node i with an edge. The direction of the edge is from node i to each node in graph[i]. If a node has &lt;strong&gt;no outgoing edges&lt;/strong&gt; , it is considered a &lt;strong&gt;terminal node&lt;/strong&gt; . If &lt;strong&gt;all possible paths&lt;/strong&gt; from a node ** lead to terminal nodes**, the node is considered a ** safe node**.&lt;/p&gt;
&lt;p&gt;The task is to find all the safe nodes in the graph and return them in &lt;strong&gt;ascending order&lt;/strong&gt; as an array (or list). To determine if a node is a safe node, we need to check if there are any cycles in the paths starting from that node. ** If there is a cycle, the node itself and all the nodes in the cycle will not be safe nodes.** Additionally, since we need to check that all paths are cycle-free to determine a safe node, ** the results from earlier checks for nodes can be applied to later checks.**&lt;/p&gt;
&lt;p&gt;To solve this problem, we can use a depth-first search (&lt;strong&gt;DFS&lt;/strong&gt; ) approach to traverse each node and its paths until the end (or until we can determine if there is a cycle). The steps for solving the problem are as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Initialize two arrays/lists, &lt;strong&gt;vis&lt;/strong&gt; and ** path**, to keep track of whether a node has been visited and whether it is part of a cycle. Both arrays/lists should have a length equal to the number of nodes in the graph, n, and initialized with 0 (or False).&lt;/li&gt;
&lt;li&gt;Initialize an empty result list called &lt;strong&gt;res&lt;/strong&gt; .&lt;/li&gt;
&lt;li&gt;Declare a DFS function that takes the &lt;strong&gt;current node, graph&lt;/strong&gt; , &lt;strong&gt;vis&lt;/strong&gt; , and &lt;strong&gt;path&lt;/strong&gt; as parameters and returns ** True if a cycle is found** and ** False if no cycle is found**.&lt;/li&gt;
&lt;li&gt;In the DFS function, perform the following steps: &lt;br&gt;
4.1. Set &lt;strong&gt;vis[curr]&lt;/strong&gt; and ** path[curr]** to ** 1** (indicating that the node has been visited and is temporarily part of a cycle). &lt;br&gt;
4.2. Iterate over the &lt;strong&gt;nodes u in graph[curr]&lt;/strong&gt; : &lt;br&gt;
4.2.1. &lt;strong&gt;If vis[u] is 0&lt;/strong&gt; (indicating that the node hasn’t been visited), recursively call DFS with u as the current node and check if it returns True. ** If True, return True (indicating a cycle is found)&lt;strong&gt;. &lt;br&gt;
4.2.2. Otherwise, if &lt;strong&gt;path[u] == 1&lt;/strong&gt; (indicating that u is already part of a cycle), return ** True&lt;/strong&gt;. &lt;br&gt;
4.3. After the &lt;strong&gt;loop ends without returning True&lt;/strong&gt; , it means there is &lt;strong&gt;no cycle found&lt;/strong&gt; when going down from the current node. ** Reset path[curr] to 0 and return False. (Since we set all the path[curr] alone with 1, we need to set it back)**&lt;/li&gt;
&lt;li&gt;In the main function, use a loop to iterate over i from &lt;strong&gt;0 to n-1&lt;/strong&gt; . If vis[i] is 0, call DFS with i as the current node.&lt;/li&gt;
&lt;li&gt;After all iterations, use another loop to iterate over i from &lt;strong&gt;0 to n-1&lt;/strong&gt; and add the nodes i with path[i] == 0 to the res list.&lt;/li&gt;
&lt;li&gt;Return the res list.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here is the code implementation in both Java and Python:&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;In the Java implementation, an ArrayList is used for the &lt;code&gt;res&lt;/code&gt; variable. If we want to reduce the number of parameters passed to the &lt;code&gt;dfs&lt;/code&gt; function, we can make &lt;code&gt;vis&lt;/code&gt; and &lt;code&gt;path&lt;/code&gt; class variables. However, since their lengths are tied to the number of nodes in the graph, they still need to be initialized within the &lt;code&gt;eventualSafeNodes&lt;/code&gt; method.&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/a0d407e4d47566801d4644afb900a168.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;As mentioned before, in the Python implementation, using nested functions can slightly reduce the number of variables that need to be passed as arguments. In fact, if we move the &lt;code&gt;vis&lt;/code&gt; and &lt;code&gt;path&lt;/code&gt; arrays/lists to the outermost scope, they don&amp;rsquo;t need to be passed as arguments at all because the nested function can access variables from the outer scope.&lt;/p&gt;
&lt;p&gt;You may try rewriting the code and experimenting with this approach.&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/182d787f4f43559379a39a192c1ffe24.js"&gt;&lt;/script&gt;
&lt;p&gt;&lt;strong&gt;Potential Interview Questions:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;“What are the time and space complexities?”&lt;/strong&gt;&lt;br&gt;
(&lt;strong&gt;O(V+E)/O(V)&lt;/strong&gt; , where V is the number of nodes in the graph and E is the number of edges in the graph)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;“Can we use a single array/list to handle visited nodes and cycles?”&lt;/strong&gt; (Hint: State can have more than 1 or 0; &lt;br&gt;
you can use 3 different states to handle this)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Similar and Extended Topics:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Special thanks to suggestions/corrections from viewers:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;(Welcome to provide feedback to help with corrections~)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Learn Algorithms from LeetCode — See you next time!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Want to see more problems? &lt;br&gt;
Feel free to check out &lt;a class="link" href="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-0/" &gt;&lt;strong&gt;Article 0&lt;/strong&gt; &lt;/a&gt; for the topic you want!&lt;/p&gt;
&lt;p&gt;Also, follow our Facebook page for notifications on new articles:&lt;br&gt;
&lt;a class="link" href="https://www.facebook.com/learnwithdesolve" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Learn with Desolve&lt;/strong&gt; &lt;/a&gt;&lt;/p&gt;</description></item><item><title>從LeetCode學演算法-121 (0802. Find Eventual Safe States)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-121-0802-find-eventual-safe-states/</link><pubDate>Wed, 01 May 2024 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-121-0802-find-eventual-safe-states/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法-121 (0802. Find Eventual Safe States)" /&gt;&lt;h2 id="categories-graphdfs"&gt;Categories: Graph/DFS
&lt;/h2&gt;&lt;h2 id="level-medium"&gt;Level: Medium
&lt;/h2&gt;&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&gt;&lt;p&gt;(基礎+進階+面試篇)從 LeetCode 學演算法 + 面試成功指南**&lt;/p&gt;
&lt;p&gt;(3591元有效期限至 2024/05/16 23:59)&lt;br&gt;
&lt;a class="link" href="https://hiskio.com/bundles/egb397?s=tc" target="_blank" rel="noopener"
&gt;https://hiskio.com/bundles/egb397?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;There is a directed graph of &lt;code&gt;n&lt;/code&gt; nodes with each node labeled from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;n - 1&lt;/code&gt;. The graph is represented by a &lt;strong&gt;0-indexed&lt;/strong&gt; 2D integer array &lt;code&gt;graph&lt;/code&gt; where &lt;code&gt;graph[i]&lt;/code&gt; is an integer array of nodes adjacent to node &lt;code&gt;i&lt;/code&gt;, meaning there is an edge from node &lt;code&gt;i&lt;/code&gt; to each node in &lt;code&gt;graph[i]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A node is a &lt;strong&gt;terminal node&lt;/strong&gt; if there are no outgoing edges. A node is a ** safe node** if every possible path starting from that node leads to a ** terminal node** (or another safe node).&lt;/p&gt;
&lt;p&gt;Return &lt;em&gt;an array containing all the&lt;/em&gt; *&lt;strong&gt;safe nodes&lt;/strong&gt; * &lt;em&gt;of the graph&lt;/em&gt;. The answer should be sorted in &lt;strong&gt;ascending&lt;/strong&gt; order.&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-121-0802-find-eventual-safe-states/image-001.png"
width="800"
height="228"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-121-0802-find-eventual-safe-states/image-001_hu_a8658ffdefe37f65.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-121-0802-find-eventual-safe-states/image-001_hu_43b3ee2d7a89e4a5.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="350"
data-flex-basis="842px"
&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;/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: graph = [[1,2],[2,3],[5],[0],[5],[],[]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [2,4,5,6]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: The given graph is shown above.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Nodes 5 and 6 are terminal nodes as there are no outgoing edges from either of them.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Every path starting at nodes 2, 4, 5, and 6 all lead to either node 5 or 6.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-2"&gt;Example 2
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;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;Input: graph = [[1,2,3,4],[1,2],[3,4],[0,4],[]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [4]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Only node 4 is a terminal node, and every path starting at node 4 leads to node 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;h3 id="constraints"&gt;Constraints
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;n == graph.length&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1 &amp;lt;= n &amp;lt;= 104&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0 &amp;lt;= graph[i].length &amp;lt;= n&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0 &amp;lt;= graph[i][j] &amp;lt;= n - 1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;graph[i]&lt;/code&gt; is sorted in a strictly increasing order.&lt;/li&gt;
&lt;li&gt;The graph may contain self-loops.&lt;/li&gt;
&lt;li&gt;The number of edges in the graph will be in the range &lt;code&gt;[1, 4 * 104]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="分析解題"&gt;分析/解題
&lt;/h2&gt;&lt;p&gt;有一個有向圖，當中包含了n個節點，每個節點分別被標記為0~n-1。&lt;br&gt;
這個圖使用2D的array graph來表示，&lt;br&gt;
當中graph[i]代表所有從節點i有邊(edge)相連的節點，&lt;br&gt;
且方向是從節點i到每個graph[i]中的節點。&lt;/p&gt;
&lt;p&gt;如果一個節點&lt;strong&gt;沒有任何向外的邊&lt;/strong&gt; 的話，則該節點是&lt;strong&gt;terminal node&lt;/strong&gt; ；&lt;br&gt;
如果從一個節點出去的&lt;strong&gt;所有可能的路徑&lt;/strong&gt; 都&lt;strong&gt;導向到terminal node&lt;/strong&gt; 的話，&lt;br&gt;
則該節點是&lt;strong&gt;safe node&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;試找出所有圖中的safe nodes，並且以陣列(串列)型態回傳，&lt;br&gt;
當中答案必須要以&lt;strong&gt;升冪排序&lt;/strong&gt; (由小到大排列)。&lt;/p&gt;
&lt;p&gt;首先我們要思考的是，怎麼樣的狀況下會沒辦法terminal呢？&lt;br&gt;
按照定義，一旦導到&lt;strong&gt;terminal node&lt;/strong&gt; ，則由於沒有向外的邊，&lt;br&gt;
於是路徑就會停在terminal node了(因為&lt;strong&gt;無路可走&lt;/strong&gt; )。&lt;br&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;因此，要判斷一個點是否為safe node，&lt;br&gt;
端看從該點出發的路徑&lt;strong&gt;是否存在有環&lt;/strong&gt; ；&lt;br&gt;
如果有環的話，&lt;strong&gt;則包含該點，以及環上的所有節點都不會是safe node&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;同時，由於我們判斷safe node必須要&lt;strong&gt;所有路徑&lt;/strong&gt; 都沒有環存在，&lt;br&gt;
&lt;strong&gt;因此前面檢查過的節點結果，會同樣適用於後面的檢查&lt;/strong&gt; 。&lt;br&gt;
例如：從點A出發，如果其中一條路徑我們走過點B跟點C，&lt;br&gt;
那麼下次當檢查從點B出發的時候，&lt;br&gt;
我們可以直接採納前面點A出發經過點B時對點B判斷的結果，&lt;br&gt;
如此一來就不用重新再走一遍了！&lt;/p&gt;
&lt;p&gt;那麼這題應該要做的就是遍歷每一個節點及路徑，&lt;br&gt;
並且每條路徑都走到底(或者走到可以判定是否有環)為止，&lt;br&gt;
這顯然適用於DFS的做法。&lt;/p&gt;
&lt;p&gt;讓我們來試著列看看解題步驟：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;初始化兩個陣列(串列) &lt;strong&gt;vis, path&lt;/strong&gt; ，分別代表該節點是否已造訪過，&lt;br&gt;
以及該節點是否為某個環的一部分，兩者的長度均為graph的節點數量n，&lt;br&gt;
預設值均為0(或False也可以)。&lt;/li&gt;
&lt;li&gt;初始化一個空的res串列備用。&lt;/li&gt;
&lt;li&gt;宣告一個dfs函式，代入&lt;strong&gt;curr, graph, vis, path&lt;/strong&gt; (curr為要檢查的node)，&lt;br&gt;
其回傳&lt;strong&gt;True則代表存在環，False則代表不存在環&lt;/strong&gt; 。&lt;/li&gt;
&lt;li&gt;在dfs函式中，進行以下處理：&lt;br&gt;
4–1. 將vis[curr]和path[curr]均&lt;strong&gt;設為1&lt;/strong&gt; (也就是已造訪，且&lt;strong&gt;暫定環存在&lt;/strong&gt; )&lt;br&gt;
4–2. 迴圈從&lt;strong&gt;graph[curr]&lt;/strong&gt; 中取出節點u：&lt;br&gt;
4–2–1. 若vis[u]為0 (表示這個節點還沒被造訪) -&amp;gt; &lt;br&gt;
代入到dfs往下檢查，如得到回傳True的話則也回傳True(代表確定有環)&lt;br&gt;
4–2–2. 否則，若&lt;strong&gt;path[u] == 1&lt;/strong&gt; (表示** u在環上**)，回傳True。&lt;br&gt;
4–3. 經過迴圈結束後尚未回傳，代表其實從curr往下走並不存在環，&lt;br&gt;
這時候重新將&lt;strong&gt;path[curr]設為0&lt;/strong&gt; ，並且回傳&lt;strong&gt;False&lt;/strong&gt; 。&lt;br&gt;
(前面直接回傳True的時候，因為我們預先將沿路的path[curr]設為1，&lt;br&gt;
因此離開的時候&lt;strong&gt;整條路徑上的節點都被標記成環了&lt;/strong&gt; ；&lt;br&gt;
反過來說，當發現不存在環的時候，&lt;strong&gt;該還原的就要還原回來&lt;/strong&gt; 。)&lt;/li&gt;
&lt;li&gt;在主函式中，使用迴圈令i依次從&lt;strong&gt;0~n-1&lt;/strong&gt; ，&lt;br&gt;
如果&lt;strong&gt;vis[i] == 0&lt;/strong&gt; 的話，就代入進行dfs。&lt;/li&gt;
&lt;li&gt;都做完的狀況下，再次使用迴圈令i從&lt;strong&gt;0~n-1&lt;/strong&gt; ，&lt;br&gt;
將&lt;strong&gt;path[i] == 0&lt;/strong&gt; 的&lt;strong&gt;i&lt;/strong&gt; 加入到res。&lt;/li&gt;
&lt;li&gt;回傳res。&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的部分使用了ArrayList給res使用，&lt;br&gt;
如果想要讓dfs不要帶入那麼多東西的話，&lt;br&gt;
也可以將vis跟path設定為class variables，&lt;br&gt;
不過因為長度跟graph的節點數掛勾，&lt;br&gt;
所以還是要在eventualSafeNodes裡才能初始化。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/a0d407e4d47566801d4644afb900a168.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分如同以前提到過的，&lt;br&gt;
使用子函式也可以稍微減少需要代入的變數量，&lt;br&gt;
甚至將vis和path放最前面的話也可以連它們都不需要代入，&lt;br&gt;
因為子函式可以去取得到上面這層的變數。&lt;br&gt;
(讀者可以自行嘗試再改寫看看)&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/182d787f4f43559379a39a192c1ffe24.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間／空間複雜度？」&lt;br&gt;
(O(V+E)/O(V)，V為graph的節點數，E為graph的邊數)&lt;/p&gt;
&lt;p&gt;「能不能只用一個陣列／串列來處理經過的節點和環？」&lt;br&gt;
(提示：State可以不只有1或0，可以設定3種state來處理)&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>Learn Algorithms from LeetCode - 119 (0797. All Paths From Source to Target(Medium))</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-119-0797-all-paths-from-source-to-target-medium/</link><pubDate>Sun, 04 Jun 2023 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-119-0797-all-paths-from-source-to-target-medium/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post Learn Algorithms from LeetCode - 119 (0797. All Paths From Source to Target(Medium))" /&gt;&lt;h2 id="categories-graphdfs"&gt;Categories: Graph/DFS
&lt;/h2&gt;&lt;h2 id="level-medium"&gt;Level: Medium
&lt;/h2&gt;&lt;p&gt;Introduction: (Basic + Advanced + Interview Edition) &lt;br&gt;
Learning Algorithms from LeetCode + Interview Success Guide &lt;br&gt;
(Regular price: 3591 NTD, Discounted price until 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;(Regular price: 3990 NTD, Valid for a long term) &lt;br&gt;
&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;Please help me click on the “SHOW EMBED” below and give it 5 likes~ If you like it, you can also give me a round of applause~ &lt;br&gt;
(Liking doesn’t cost anything, thank you for supporting my writing~)&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a directed acyclic graph (&lt;strong&gt;DAG&lt;/strong&gt; ) of &lt;code&gt;n&lt;/code&gt; nodes labeled from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;n - 1&lt;/code&gt;, find all possible paths from node &lt;code&gt;0&lt;/code&gt; to node &lt;code&gt;n - 1&lt;/code&gt; and return them in &lt;strong&gt;any order&lt;/strong&gt; .&lt;/p&gt;
&lt;p&gt;The graph is given as follows: &lt;code&gt;graph[i]&lt;/code&gt; is a list of all nodes you can visit from node &lt;code&gt;i&lt;/code&gt; (i.e., there is a directed edge from node &lt;code&gt;i&lt;/code&gt; to node &lt;code&gt;graph[i][j]&lt;/code&gt;).&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-119-0797-all-paths-from-source-to-target-medium/0_JZvZO8TcGYlV_krH.jpg"
width="242"
height="242"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-119-0797-all-paths-from-source-to-target-medium/0_JZvZO8TcGYlV_krH_hu_60b1ca5817f91f36.jpg 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-119-0797-all-paths-from-source-to-target-medium/0_JZvZO8TcGYlV_krH_hu_e1c4b444c3304661.jpg 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="100"
data-flex-basis="240px"
&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: graph = [[1,2],[3],[3],[]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [[0,1,3],[0,2,3]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: There are two paths: 0 -&amp;gt; 1 -&amp;gt; 3 and 0 -&amp;gt; 2 -&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="example-2"&gt;Example 2
&lt;/h3&gt;&lt;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-119-0797-all-paths-from-source-to-target-medium/0_205SEP480YZHWDkX.jpg"
width="423"
height="301"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-119-0797-all-paths-from-source-to-target-medium/0_205SEP480YZHWDkX_hu_ec6726b91810384e.jpg 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-119-0797-all-paths-from-source-to-target-medium/0_205SEP480YZHWDkX_hu_694746669cf369eb.jpg 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="140"
data-flex-basis="337px"
&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: graph = [[4,3,1],[3,2,4],[3],[4],[]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,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;h3 id="constraints"&gt;Constraints
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;n == graph.length&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;2 &amp;lt;= n &amp;lt;= 15&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0 &amp;lt;= graph[i][j] &amp;lt; n&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;graph[i][j] != i&lt;/code&gt; (i.e., there will be no self-loops).&lt;/li&gt;
&lt;li&gt;All the elements of &lt;code&gt;graph[i]&lt;/code&gt; are &lt;strong&gt;unique&lt;/strong&gt; .&lt;/li&gt;
&lt;li&gt;The input graph is &lt;strong&gt;guaranteed&lt;/strong&gt; to be a ** DAG**.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Analysis/Approach:&lt;/strong&gt; &lt;br&gt;
Given a directed acyclic graph (DAG) with n nodes labeled from 0 to n — 1, we need to find all possible paths from node 0 to node n — 1 and return them in any order.&lt;/p&gt;
&lt;p&gt;The graph is represented in the following way: graph[i] represents a list of nodes that can be visited from node i. (Directly visiting means there is a directed edge from node i to graph[i][j].)&lt;/p&gt;
&lt;p&gt;Let’s talk about graphs in this article. As mentioned in &lt;a class="link" href="https://desolve.medium.com/%E5%BE%9Eleetcode%E5%AD%B8%E6%BC%94%E7%AE%97%E6%B3%95-115-graph-1-union-find-1-3616ad4a6496" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Article 115&lt;/strong&gt; &lt;/a&gt;, in a graph with directionality (a -&amp;gt; b and b -&amp;gt; a are considered different edges), it is called a &lt;strong&gt;directed graph&lt;/strong&gt; . If a directed graph does not have cycles (a &lt;strong&gt;cycle&lt;/strong&gt; means there is a path starting from a point a and ending at a, forming a loop), it is called a ** directed acyclic graph**, abbreviated as ** DAG**.&lt;/p&gt;
&lt;p&gt;Since the problem guarantees that the graph is a DAG, it is impossible to return to the same node from any starting node, and it is also impossible to backtrack, meaning there are no duplicates in the paths.&lt;/p&gt;
&lt;p&gt;Let’s try to outline the steps to find the paths:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Start from i = 0 and examine the connections in &lt;strong&gt;graph[i]&lt;/strong&gt; . For example, in Example 1, node 0 connects to nodes 1 and 2, so there are two paths: 0-&amp;gt;1 and 0-&amp;gt;2.&lt;/li&gt;
&lt;li&gt;For the path 0-&amp;gt;1, we need to check the connections from node 1. It is connected only to node 3, which happens to be the last node in this graph. Therefore, we have found one valid path: 0-&amp;gt;1-&amp;gt;3.&lt;/li&gt;
&lt;li&gt;Similarly, for the path 0-&amp;gt;2, it only has one connection: 0-&amp;gt;2-&amp;gt;3.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Therefore, for this problem, we can use DFS starting from node 0 and recursively explore the graph. Along the way, we need to keep track of the current path at each step. Whenever we reach the destination node, we add that path to the result list. Finally, we return the entire result.&lt;/p&gt;
&lt;p&gt;The steps for solving this problem are as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Initialize a list called res to store the resulting paths.&lt;/li&gt;
&lt;li&gt;Define a function dfs with parameters (i, path), where i is the current node and path is the path taken to reach node i (including i).&lt;/li&gt;
&lt;li&gt;Inside the function, first check if i is equal to the length of the graph minus 1. If true, it means we have reached node n-1, and this path is one of the answers. Add it to res.&lt;/li&gt;
&lt;li&gt;If the previous check fails, it means we need to continue exploring. Iterate through the next node nxt in graph[i] and recursively call dfs with nxt and the updated path (path + nxt).&lt;/li&gt;
&lt;li&gt;Start the recursion by calling dfs with (0, [0]).&lt;/li&gt;
&lt;li&gt;After Step 5 is completed, return res.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Based on this, the code can be written as follows:&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;In Java, the res list is obviously two-dimensional, so we can use an ArrayList to store the paths. In the helper (or dfs) function, since we cannot use nested functions like in Python, we need to include graph, i, path, and res as parameters. Since the path is reused in each recursion, we use backtracking to keep track of the path. In each call to the helper function, we add the current node i to the path (path.add(i)), and remember to remove it (path.remove(path.size() — 1)) before exiting.&lt;/p&gt;
&lt;p&gt;One important thing to note is that when adding paths to res, ArrayList is a reference-based structure, meaning it doesn’t create a copy of the path. Therefore, when adding to res, we need to use new ArrayList(path) to create a copy. Otherwise, when we backtrack, it will affect the results in res.&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/f8e5a08fab8cce5a8c5118d8725791b7.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;In Python, we can use nested functions, so we don’t need to include res and graph as parameters, which makes the code cleaner. When performing dfs, we can directly create a new list using &lt;strong&gt;path + [nxt]&lt;/strong&gt; . This way, we don’t need to deal with backtracking, and we can directly append path to res without making a separate copy. (Since path + [nxt] creates a new list already.)&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/edc9788f87792c4c6dc14a112f7ee51a.js"&gt;&lt;/script&gt;
&lt;p&gt;&lt;strong&gt;Potential Interview Questions:&lt;/strong&gt;&lt;br&gt;
“What are the time and space complexities?” (O(V * 2^V), as each path has a maximum complexity of O(V), and there can be up to O(2^V) paths.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Similar and Extended Topics:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Special thanks to suggestions/corrections from viewers:&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;(Welcome to provide feedback to help with corrections~)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Learn Algorithms from LeetCode — See you next time!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Want to see more problems? &lt;br&gt;
Feel free to check out &lt;a class="link" href="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-0/" &gt;&lt;strong&gt;Article 0&lt;/strong&gt; &lt;/a&gt; for the topic you want!&lt;/p&gt;
&lt;p&gt;Also, follow our Facebook page for notifications on new articles:&lt;br&gt;
&lt;a class="link" href="https://www.facebook.com/learnwithdesolve" target="_blank" rel="noopener"
&gt;&lt;strong&gt;Learn with Desolve&lt;/strong&gt; &lt;/a&gt;&lt;/p&gt;</description></item><item><title>從LeetCode學演算法 - 119 Graph (2) / DFS (21)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-119-graph-2-dfs-21/</link><pubDate>Sun, 04 Jun 2023 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-119-graph-2-dfs-21/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 119 Graph (2) / DFS (21)" /&gt;&lt;p&gt;&lt;strong&gt;0797. All Paths From Source to Target (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;Given a directed acyclic graph (&lt;strong&gt;DAG&lt;/strong&gt; ) of &lt;code&gt;n&lt;/code&gt; nodes labeled from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;n - 1&lt;/code&gt;, find all possible paths from node &lt;code&gt;0&lt;/code&gt; to node &lt;code&gt;n - 1&lt;/code&gt; and return them in &lt;strong&gt;any order&lt;/strong&gt; .&lt;/p&gt;
&lt;p&gt;The graph is given as follows: &lt;code&gt;graph[i]&lt;/code&gt; is a list of all nodes you can visit from node &lt;code&gt;i&lt;/code&gt; (i.e., there is a directed edge from node &lt;code&gt;i&lt;/code&gt; to node &lt;code&gt;graph[i][j]&lt;/code&gt;).&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-119-graph-2-dfs-21/0_JZvZO8TcGYlV_krH.jpg"
width="242"
height="242"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-119-graph-2-dfs-21/0_JZvZO8TcGYlV_krH_hu_60b1ca5817f91f36.jpg 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-119-graph-2-dfs-21/0_JZvZO8TcGYlV_krH_hu_e1c4b444c3304661.jpg 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="100"
data-flex-basis="240px"
&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: graph = [[1,2],[3],[3],[]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [[0,1,3],[0,2,3]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: There are two paths: 0 -&amp;gt; 1 -&amp;gt; 3 and 0 -&amp;gt; 2 -&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="example-2"&gt;Example 2
&lt;/h3&gt;&lt;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-119-graph-2-dfs-21/0_205SEP480YZHWDkX.jpg"
width="423"
height="301"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-119-graph-2-dfs-21/0_205SEP480YZHWDkX_hu_ec6726b91810384e.jpg 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-119-graph-2-dfs-21/0_205SEP480YZHWDkX_hu_694746669cf369eb.jpg 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="140"
data-flex-basis="337px"
&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: graph = [[4,3,1],[3,2,4],[3],[4],[]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,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;h3 id="constraints"&gt;Constraints
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;n == graph.length&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;2 &amp;lt;= n &amp;lt;= 15&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0 &amp;lt;= graph[i][j] &amp;lt; n&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;graph[i][j] != i&lt;/code&gt; (i.e., there will be no self-loops).&lt;/li&gt;
&lt;li&gt;All the elements of &lt;code&gt;graph[i]&lt;/code&gt; are &lt;strong&gt;unique&lt;/strong&gt; .&lt;/li&gt;
&lt;li&gt;The input graph is &lt;strong&gt;guaranteed&lt;/strong&gt; to be a ** DAG**.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一個有向無環圖(directed acyclic graph, DAG)，&lt;br&gt;
當中有n個nodes，分別被標記為0到n - 1，&lt;br&gt;
找出所有可以從node 0走到node n - 1的路徑，&lt;br&gt;
並且以任意排序的方式回傳。&lt;/p&gt;
&lt;p&gt;graph的給定方式如以下敘述：&lt;br&gt;
graph[i] 代表所有從node i可以造訪的nodes的串列。&lt;br&gt;
(直接造訪，也就是指node i到graph[i][j]之間會有一個有方向的edge(邊))&lt;/p&gt;
&lt;p&gt;我們這篇再來談談graph。&lt;br&gt;
之前我們在&lt;a class="link" href="https://desolve.medium.com/%E5%BE%9Eleetcode%E5%AD%B8%E6%BC%94%E7%AE%97%E6%B3%95-115-graph-1-union-find-1-3616ad4a6496" target="_blank" rel="noopener"
&gt;&lt;strong&gt;第115篇&lt;/strong&gt; &lt;/a&gt;提到過，&lt;br&gt;
在graph當中，有方向性的(a -&amp;gt; b和 b -&amp;gt; a被視為不一樣的邊)圖，&lt;br&gt;
被稱為&lt;strong&gt;有向圖(directed graph)&lt;/strong&gt; ；而如果有向圖中，&lt;br&gt;
不存在&lt;strong&gt;環(cycle，也就是圖上存在一個點a，從點a出發，&lt;br&gt;
有一條路徑可以再走回點a)&lt;strong&gt;的話，&lt;br&gt;
則稱為&lt;/strong&gt;有向無環圖&lt;/strong&gt; ，簡寫為DAG。&lt;/p&gt;
&lt;p&gt;既然題目保證圖是DAG，那麼我們從任何一個點出發，&lt;br&gt;
都保證不可能會再回到同一個點，同時也不可能走回頭路，&lt;br&gt;
也就不存在重複的可能。&lt;/p&gt;
&lt;p&gt;讓我們嘗試列出找尋路徑的步驟：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;首先從i = 0開始，觀察&lt;strong&gt;graph[i]&lt;/strong&gt; 的連接，&lt;br&gt;
例如像Example 1中0就連到1跟2，&lt;br&gt;
也就是說會有 &lt;strong&gt;0-&amp;gt;1&lt;/strong&gt; 跟&lt;strong&gt;0-&amp;gt;2&lt;/strong&gt; 這兩條路徑&lt;/li&gt;
&lt;li&gt;對於0-&amp;gt;1而言，接下來我們要看1的連接，&lt;br&gt;
發現它只連接到3，而3剛好是這個graph的最後一個節點，&lt;br&gt;
因此得到其中一個有效的路徑是0-&amp;gt;1-&amp;gt;3。&lt;/li&gt;
&lt;li&gt;同理，對於0-&amp;gt;2而言也剛好只有0-&amp;gt;2-&amp;gt;3。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;因此對於這題，我們可以使用DFS從node 0做遞迴往下，&lt;br&gt;
中途要記住每一步當下走過的路徑，只要有走到終點的路徑，&lt;br&gt;
就將其放到答案的列表裡，最後再將整個結果回傳即可。&lt;/p&gt;
&lt;p&gt;列出解題步驟如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;初始化一個串列res，用以存放結果的路徑&lt;/li&gt;
&lt;li&gt;定義一個dfs的函式，輸入為**(i, path)** ，&lt;br&gt;
當中i為當前走到的node，path為走到node i時經過的路徑(&lt;strong&gt;包含i&lt;/strong&gt; )。&lt;/li&gt;
&lt;li&gt;在函式中，首先檢查i是否和graph的長度-1相等，&lt;br&gt;
如是，代表走到&lt;strong&gt;node n-1&lt;/strong&gt; 的位置了，&lt;br&gt;
&lt;strong&gt;該路徑是答案之一，將其加到res上&lt;/strong&gt; 。&lt;/li&gt;
&lt;li&gt;若3的檢查解果為否，代表要繼續往下走，&lt;br&gt;
迴圈遍歷&lt;strong&gt;graph[i]&lt;/strong&gt; 中的下一個node nxt，&lt;br&gt;
並呼叫dfs，將&lt;strong&gt;node nxt&lt;/strong&gt; 和新的path(&lt;strong&gt;path加上nxt&lt;/strong&gt; )代入遞迴。&lt;/li&gt;
&lt;li&gt;將**(0, [0])** 代入dfs中開始遞迴。&lt;/li&gt;
&lt;li&gt;完成5後，將res回傳即可。&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的部分，我們的res顯然是二維的，&lt;br&gt;
因此我們可以使用ArrayList來放入其中。&lt;br&gt;
在helper(或dfs)中，因為不能像Python使用子函式，&lt;br&gt;
這邊參數就需要graph、i、path、res；&lt;br&gt;
又因為path是反覆遞迴下去利用的，&lt;br&gt;
我們在記錄時使用backtracking的方式，&lt;br&gt;
選擇在每次進入helper函式時，將path給加上當前走到的node i，&lt;br&gt;
在離開時，則要記得將其收回，因此分別會在頭尾做&lt;strong&gt;path.add(i)&lt;/strong&gt; ，&lt;br&gt;
以及&lt;strong&gt;path.remove(path.size()-1)&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;其他要留意的部分是，由於在放到res的時候，&lt;br&gt;
對於ArrayList來說是一個指向性質的放置，並不會直接複製一份path，&lt;br&gt;
所以在res.add的時候，必須要使用&lt;strong&gt;new ArrayList(path)&lt;/strong&gt; 的手法，&lt;br&gt;
將path複製一份出來才行；不然後面我們在backtracking的時候，&lt;br&gt;
就會同步影響到res的結果喲！&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/f8e5a08fab8cce5a8c5118d8725791b7.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;在Python的部分由於可以使用子函式，&lt;br&gt;
我們可以不需要再將res跟graph加到參數，&lt;br&gt;
就會簡潔一點；&lt;br&gt;
同時，在進行dfs的時候，我們這邊改成用&lt;br&gt;
&lt;strong&gt;path + [nxt]&lt;/strong&gt; 的方式，就會直接形成一個新的list。&lt;br&gt;
這樣一來，path的部分就不需要再回頭處理backtracking的問題，&lt;br&gt;
同時res也可以直接進行append(path)，不需要另行複製。&lt;br&gt;
(因為前面path + [nxt]時已經複製完path並形成一個新的list了)&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/edc9788f87792c4c6dc14a112f7ee51a.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(V * 2^V)，因為單一條最多是O(V)，最多可能有O(2^V)條)&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學演算法 - 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學演算法 - 116 Tree (21) / DFS (19)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-116-tree-21-dfs-19/</link><pubDate>Tue, 21 Sep 2021 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-116-tree-21-dfs-19/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 116 Tree (21) / DFS (19)" /&gt;&lt;p&gt;&lt;strong&gt;0814. Binary Tree Pruning (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&gt;&lt;p&gt;(基礎+進階+面試篇) 從 LeetCode 學演算法 + 面試成功指南**&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;strong&gt;初學 Python 的第一本書 : 從基本語法到模組應用（iT邦幫忙鐵人賽系列書）&lt;/strong&gt; &lt;a class="link" href="https://www.tenlong.com.tw/products/9789864348503" target="_blank" rel="noopener"
&gt;https://www.tenlong.com.tw/products/9789864348503&lt;/a&gt;&lt;br&gt;
這本書主要是針對初學Python的入門讀者，希望能夠提供一個得以從零開始上手，又不會太過冗長的入門學習書。有興趣的話請多多支持！&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/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 the &lt;code&gt;root&lt;/code&gt; of a binary tree, return &lt;em&gt;the same tree where every subtree (of the given tree) not containing a&lt;/em&gt; &lt;code&gt;1&lt;/code&gt; &lt;em&gt;has been removed&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;A subtree of a node &lt;code&gt;node&lt;/code&gt; is &lt;code&gt;node&lt;/code&gt; plus every node that is a descendant of &lt;code&gt;node&lt;/code&gt;.&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-116-tree-21-dfs-19/0_5zTxC9JnDF8GRDhz.png"
width="800"
height="224"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-116-tree-21-dfs-19/0_5zTxC9JnDF8GRDhz_hu_3229419e65641c69.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-116-tree-21-dfs-19/0_5zTxC9JnDF8GRDhz_hu_9fe37af931d61d84.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="357"
data-flex-basis="857px"
&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;/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: root = [1,null,0,0,1]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [1,null,0,null,1]
&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;Only the red nodes satisfy the property &amp;#34;every subtree not containing a 1&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;The diagram on the right represents the answer.
&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;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-116-tree-21-dfs-19/0_E1Tq4_L1vjGx8RqU.png"
width="800"
height="184"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-116-tree-21-dfs-19/0_E1Tq4_L1vjGx8RqU_hu_f177f01d2062f25e.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-116-tree-21-dfs-19/0_E1Tq4_L1vjGx8RqU_hu_e46343ca46cdc39a.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="434"
data-flex-basis="1043px"
&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: root = [1,0,1,0,0,0,1]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [1,null,1,null,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-3"&gt;Example 3
&lt;/h3&gt;&lt;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-116-tree-21-dfs-19/0_5yuz2kYgJcGvgU2x.png"
width="800"
height="215"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-116-tree-21-dfs-19/0_5yuz2kYgJcGvgU2x_hu_cb5bd4c11095c465.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-116-tree-21-dfs-19/0_5yuz2kYgJcGvgU2x_hu_960d09212f347a67.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="372"
data-flex-basis="893px"
&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: root = [1,1,0,1,1,0,1,0]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [1,1,0,1,1,null,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;The number of nodes in the tree is in the range &lt;code&gt;[1, 200]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Node.val&lt;/code&gt; is either &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一個二元樹的root，將同一棵樹中未含任何1的子樹均去除掉並回傳。&lt;br&gt;
(限制條件：樹的節點數目在1~200之間，且Node的值只會是0或1)&lt;/p&gt;
&lt;p&gt;如果我們看到範例的話，大致上可以理解要被去掉的部分就是包括自己以及其底下的所有節點值均為0的子樹，這樣才能保證剩下的符合題目要求的條件。&lt;/p&gt;
&lt;p&gt;因此，我們總體要做的就是檢查一棵樹的左子樹及右子樹狀況，&lt;br&gt;
然後分別決定左子樹/右子樹是否要被去掉，最後將當棵樹的總體狀況往上回傳，因此，設計一個子函數helper如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;傳入要檢查的節點n&lt;/li&gt;
&lt;li&gt;如果n是空節點，則直接回傳0(因為這代表往下左右沒有其它節點了，也不用繼續檢查)&lt;/li&gt;
&lt;li&gt;遞迴檢查左子樹(將n.left代入helper)，取得左子樹含1的節點數量為l&lt;/li&gt;
&lt;li&gt;遞迴檢查右子樹(將n.right代入helper)，取得右子樹含1的節點數量為r&lt;/li&gt;
&lt;li&gt;若l為0，表示無左子樹或左子樹均無節點值為1的節點，將n.left設為NIL&lt;/li&gt;
&lt;li&gt;同理，若r為0，將n.right設為NIL&lt;/li&gt;
&lt;li&gt;回傳l+r+n.val&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在將root代入helper遞迴結束後，所有root的子樹應該都被清乾淨了，&lt;br&gt;
除了root自己以外，所以我們要檢查helper得到的最後的值，&lt;br&gt;
若為0的話，則最終我們應回傳NIL，否則應回傳root。&lt;/p&gt;
&lt;p&gt;依此，寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分使用三元運算子來處理最後的c，&lt;br&gt;
其實我們也可以將整個helper的函式使用True/False來處理，&lt;br&gt;
這樣中間的計算就要改成or來檢查是否至少存在一個節點值為1的節點。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/e76ff62f67e0540792c41c7ae6b3fa6e.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分使用子函數來簡單處理，其它的部分邏輯一樣。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/6ebdc845996a04c178cd6a6e2c727b1b.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N)/O(N)，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;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學演算法 - 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學演算法 - 108 Tree (20) / DFS (17)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/</link><pubDate>Sun, 03 Jan 2021 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 108 Tree (20) / DFS (17)" /&gt;&lt;p&gt;&lt;strong&gt;1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&gt;&lt;p&gt;好久不見！筆者最近剛換了工作，&lt;br&gt;
所以比較忙一點XD &lt;strong&gt;之後1月中會有HiSKIO 技術年貨節的活動，&lt;br&gt;
歡迎大家拿著折價券來修從LeetCode學演算法的課程喲！&lt;br&gt;
如果預算不夠，相信這108篇也還是很夠讀者練習的啦XDD&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在更之後還有規劃0元挑戰賽的部分，&lt;br&gt;
只要&lt;strong&gt;修課後一定時間內成功錄取新工作&lt;/strong&gt; ，&lt;br&gt;
&lt;strong&gt;課程就會全額退費喲！&lt;/strong&gt; 這部分再請留意官方那邊的公告，&lt;br&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;p&gt;&lt;strong&gt;「從Leetcode學演算法」全套(基礎/進階/面試篇)同捆優惠：&lt;/strong&gt;&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;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given two binary trees &lt;code&gt;original&lt;/code&gt; and &lt;code&gt;cloned&lt;/code&gt; and given a reference to a node &lt;code&gt;target&lt;/code&gt; in the original tree.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;cloned&lt;/code&gt; tree is a &lt;strong&gt;copy of&lt;/strong&gt; the &lt;code&gt;original&lt;/code&gt; tree.&lt;/p&gt;
&lt;p&gt;Return &lt;em&gt;a reference to the same node&lt;/em&gt; in the &lt;code&gt;cloned&lt;/code&gt; tree.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; that you are ** not allowed** to change any of the two trees or the &lt;code&gt;target&lt;/code&gt; node and the answer ** must be** a reference to a node in the &lt;code&gt;cloned&lt;/code&gt; tree.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Follow up:&lt;/strong&gt; Solve the problem if repeated values on the tree are allowed.&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-108-tree-20-dfs-17/0_GYOQ1UwiPY_qi4UM.png"
width="544"
height="426"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/0_GYOQ1UwiPY_qi4UM_hu_7f4c691b13b758ac.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/0_GYOQ1UwiPY_qi4UM_hu_de7dc142adc071cf.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="127"
data-flex-basis="306px"
&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: tree = [7,4,3,null,null,6,19], target = 3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: In all examples the original and cloned trees are shown. The target node is a green node from the original tree. The answer is the yellow node from the cloned tree.
&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;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/0_8XmwUepRVQFlWNjK.png"
width="221"
height="159"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/0_8XmwUepRVQFlWNjK_hu_fe0d5df90720a9ca.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/0_8XmwUepRVQFlWNjK_hu_826cf7448e681926.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="138"
data-flex-basis="333px"
&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: tree = [7], target = 7
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 7
&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;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/0_K4tA1xRKWOkLeMBq.png"
width="459"
height="486"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/0_K4tA1xRKWOkLeMBq_hu_76be706ea408d602.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/0_K4tA1xRKWOkLeMBq_hu_4f4752dc72bf39a3.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="94"
data-flex-basis="226px"
&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: tree = [8,null,6,null,5,null,4,null,3,null,2,null,1], target = 4
&lt;/span&gt;&lt;/span&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;h3 id="example-4"&gt;Example 4
&lt;/h3&gt;&lt;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/0_fRlfsY4PDxTsuWel.png"
width="800"
height="344"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/0_fRlfsY4PDxTsuWel_hu_d69dcd8ac08765e7.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/0_fRlfsY4PDxTsuWel_hu_8fd282df5ba1d125.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="232"
data-flex-basis="558px"
&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: tree = [1,2,3,4,5,6,7,8,9,10], target = 5
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 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;h3 id="example-5"&gt;Example 5
&lt;/h3&gt;&lt;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/0_2F34zOAHfHFDUEu2.png"
width="427"
height="345"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/0_2F34zOAHfHFDUEu2_hu_202c81a68a227443.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-108-tree-20-dfs-17/0_2F34zOAHfHFDUEu2_hu_fe1e7fc89f94a0a2.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="123"
data-flex-basis="297px"
&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: tree = [1,2,null,3], target = 2
&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="constraints"&gt;Constraints
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;The number of nodes in the &lt;code&gt;tree&lt;/code&gt; is in the range &lt;code&gt;[1, 10^4]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The values of the nodes of the &lt;code&gt;tree&lt;/code&gt; are unique.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;target&lt;/code&gt; node is a node from the &lt;code&gt;original&lt;/code&gt; tree and is not &lt;code&gt;null&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定兩個二元樹 original 跟 cloned ，&lt;br&gt;
並給定一個 originl 樹上的參考節點 target，&lt;br&gt;
當中，cloned是original的完全複製，&lt;br&gt;
請找到 cloned 上和 target 相對應的相同節點回傳。&lt;br&gt;
留意兩棵樹上的節點都不允許被改變，&lt;br&gt;
且答案必須要是cloned這棵樹上的對應節點。&lt;br&gt;
(而不是original上的或新作出來的節點)&lt;/p&gt;
&lt;p&gt;條件限制：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;樹上的總節點數量範圍在1到10⁴之間。&lt;/li&gt;
&lt;li&gt;樹上的各節點值均為&lt;strong&gt;獨一無二&lt;/strong&gt; 的。&lt;/li&gt;
&lt;li&gt;target是original這棵樹上的節點，且不為null。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;後續：如果重複值可被允許，嘗試在這個條件下解決問題。&lt;/p&gt;
&lt;p&gt;這題雖然標為Medium，但說實在的不難XD&lt;br&gt;
看完題目以後，已經經歷過前面各種難題的讀者，&lt;br&gt;
應該會直覺想到使用DFS來解決。&lt;/p&gt;
&lt;p&gt;那麼，由於題目一開始已經給定說值是全部獨一無二。&lt;br&gt;
如果先不計較Follow up的部分，&lt;br&gt;
其實我們可以直接比較值就可以了！&lt;br&gt;
我們可以直接將target的值當作目標，&lt;br&gt;
並且對於cloned這棵樹進行dfs，只要比較到相同的值，&lt;br&gt;
就可以進行回傳啦！&lt;br&gt;
由於1的關係，我們不用擔心使用遞迴會超過call stack限制，&lt;br&gt;
使用一個helper函式，當遇到null/None時，&lt;br&gt;
回傳null/None，接著&lt;strong&gt;檢查所在節點值是否和target的值相同&lt;/strong&gt; ；&lt;br&gt;
接著分別&lt;strong&gt;dfs往左邊和往右邊的樹進行尋找&lt;/strong&gt; 。&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;當右邊也沒有找到時，則回傳null/None&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;那麼，如果節點值不一定獨一無二呢？&lt;br&gt;
那麼我們就要同時也將original一起進行遞迴，&lt;br&gt;
這時候檢查的就是original上歷經的節點是否是target節點，&lt;br&gt;
在檢查到的時候同時去回傳cloned的對應節點。&lt;/p&gt;
&lt;p&gt;這時候我們&lt;strong&gt;用來檢查相等的就是記憶體位址，而非節點值&lt;/strong&gt; 。&lt;br&gt;
因為唯有記憶體位址相同時，能保證這個節點是對應位置的那個節點。&lt;br&gt;
(而非只有裡面的值相同)&lt;/p&gt;
&lt;p&gt;依此，我們寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分我們額外提供了LeetCode上Follow Up的解法在註解，&lt;br&gt;
使用相同的做法，應該也可以寫出Python的方法，&lt;br&gt;
讀者可以自行嘗試看看。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/af0e4cf14db21baf15da0e10aa9b4121.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分，請讀者留意，&lt;br&gt;
對Python而言，我們寫n: TreeNode, v: int這樣的格式，&lt;br&gt;
是&lt;strong&gt;寫給人看的&lt;/strong&gt; XD，讀者也可以完全都不寫，一樣可以執行。&lt;br&gt;
而且對於使用者來說，就算你將v代成不是int的東西，&lt;br&gt;
也不會直接被Python視為錯誤，&lt;br&gt;
並不像Java或其他程式語言那樣對這邊有型別檢查，&lt;br&gt;
這點請務必留意喲！&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/dd29c995eb91cf5776d22c618eed221d.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N)/O(1)，基本上最差的狀況要遍歷整棵樹，&lt;br&gt;
而空間上要計較Call Stack的話，則會跟樹的深度成正比，&lt;br&gt;
除此以外沒有其他額外和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;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學演算法 - 106 Tree (19) / DFS (16)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-106-tree-19-dfs-16/</link><pubDate>Mon, 09 Nov 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-106-tree-19-dfs-16/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 106 Tree (19) / DFS (16)" /&gt;&lt;p&gt;&lt;strong&gt;0563. Binary Tree Tilt (Easy)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&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;p&gt;&lt;strong&gt;「從Leetcode學演算法」全套(基礎/進階/面試篇)同捆優惠：&lt;/strong&gt;&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;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given the &lt;code&gt;root&lt;/code&gt; of a binary tree, return &lt;em&gt;the sum of every tree node&amp;rsquo;s&lt;/em&gt; *&lt;strong&gt;tilt&lt;/strong&gt; *&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;tilt&lt;/strong&gt; of a tree node is the ** absolute difference** between the sum of all left subtree node ** values** and all right subtree node ** values**. If a node does not have a left child, then the sum of the left subtree node ** values** is treated as &lt;code&gt;0&lt;/code&gt;. The rule is similar if there the node does not have a right child.&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-106-tree-19-dfs-16/0_n3VDsKYOs5Tivyg-.jpg"
width="712"
height="182"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-106-tree-19-dfs-16/0_n3VDsKYOs5Tivyg-_hu_f8f0e2bb9975a20e.jpg 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-106-tree-19-dfs-16/0_n3VDsKYOs5Tivyg-_hu_fa6cedeb906b0062.jpg 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="391"
data-flex-basis="938px"
&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: root = [1,2,3]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Tilt of node 2 : |0-0| = 0 (no children)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Tilt of node 3 : |0-0| = 0 (no children)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Tile of node 1 : |2-3| = 1 (left subtree is just left child, so sum is 2; right subtree is just right child, so sum is 3)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Sum of every tilt : 0 + 0 + 1 = 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;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-106-tree-19-dfs-16/0_gkWZfWiksT5c-TsC.jpg"
width="800"
height="203"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-106-tree-19-dfs-16/0_gkWZfWiksT5c-TsC_hu_1f4637af595424cb.jpg 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-106-tree-19-dfs-16/0_gkWZfWiksT5c-TsC_hu_fe4828eaf0547edf.jpg 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="394"
data-flex-basis="945px"
&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: root = [4,2,9,3,5,null,7]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 15
&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;Tilt of node 3 : |0-0| = 0 (no children)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Tilt of node 5 : |0-0| = 0 (no children)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Tilt of node 7 : |0-0| = 0 (no children)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Tilt of node 2 : |3-5| = 2 (left subtree is just left child, so sum is 3; right subtree is just right child, so sum is 5)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Tilt of node 9 : |0-7| = 7 (no left child, so sum is 0; right subtree is just right child, so sum is 7)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Tilt of node 4 : |(3+5+2)-(9+7)| = |10-16| = 6 (left subtree values are 3, 5, and 2, which sums to 10; right subtree values are 9 and 7, which sums to 16)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Sum of every tilt : 0 + 0 + 0 + 2 + 7 + 6 = 15
&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;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-106-tree-19-dfs-16/0_kb1LkOQ2Kql9Po_l.jpg"
width="800"
height="293"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-106-tree-19-dfs-16/0_kb1LkOQ2Kql9Po_l_hu_844a577989e5bf4a.jpg 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-106-tree-19-dfs-16/0_kb1LkOQ2Kql9Po_l_hu_34b639756e8b7f75.jpg 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="273"
data-flex-basis="655px"
&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: root = [21,7,14,1,1,2,2,3,3]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 9
&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;The number of nodes in the tree is in the range &lt;code&gt;[0, 104]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-1000 &amp;lt;= Node.val &amp;lt;= 1000&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一個二元樹，試計算二元樹的每個節點的tilt(坡度)和。&lt;/p&gt;
&lt;p&gt;什麼是tilt呢?&lt;br&gt;
題目告訴我們，對於一個節點，&lt;br&gt;
其左子樹的和以及右子樹的和相減的絕對值，&lt;br&gt;
就稱為它的坡度(tilt)，當子樹不存在時，和則視為0。&lt;/p&gt;
&lt;p&gt;另外由於整個樹的總節點數已經被限定在0~104之間了，&lt;br&gt;
表示我們可以放心的用遞迴！&lt;/p&gt;
&lt;p&gt;那麼，我們該怎麼對每個節點算坡度呢？&lt;br&gt;
對於一個節點n，如果它不存在的話(NIL)，&lt;br&gt;
&lt;strong&gt;其坡度自然為0，且總和同樣為0&lt;/strong&gt; ；&lt;br&gt;
存在的話，我們必須先算出&lt;strong&gt;左子樹(n.left為根節點的子樹)和，&lt;br&gt;
以及右子樹(n.right為根節點的子樹)和，將兩者相減取絕對值，&lt;br&gt;
就是n的坡度。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;因此，我們可以使用一個dfs的函式來同時處理算子樹和，&lt;br&gt;
以及坡度的部分，整個dfs的概念應該會如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;若n為NIL，回傳0&lt;/li&gt;
&lt;li&gt;將n.left代入dfs中，取得n.left的子樹和l&lt;/li&gt;
&lt;li&gt;將n.right代入dfs中，取得n.right子樹和r&lt;/li&gt;
&lt;li&gt;將|l-r|加到物件變數的答案res中&lt;/li&gt;
&lt;li&gt;回傳l+r+n.val&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;留意到我們使用dfs的回傳一直都是回傳以n為根節點的子樹和，&lt;br&gt;
這個和我們要計算的坡度不同，所以必須要用一個res變數來儲存。&lt;/p&gt;
&lt;p&gt;在寫出dfs函式後，我們只需要初始化res，&lt;br&gt;
並且在主函式中呼叫dfs後，回傳res即可。&lt;/p&gt;
&lt;p&gt;依此，寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java-對於java而言abs在javalangmath函式庫中"&gt;Java 對於Java而言abs在java.lang.Math函式庫中，
&lt;/h3&gt;&lt;p&gt;如果不是在LeetCode的編輯器的話，不要忘記自行import。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/e737e1f9dd68f2eca0b6352f790fb0a9.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分和Java大同小異，&lt;br&gt;
這邊採用將dfs寫成一個子函式，別忘記要宣告以後才能夠使用呦！&lt;br&gt;
此外，__init__並非一定要這樣使用，在class Solution中直接定義也沒問題。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/5420e6680c86b99d7f00c51bb3b55430.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N)/O(樹的深度)，最差則為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學演算法 - 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學演算法 - 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學演算法 - 102 Tree (15) / DFS (12)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-102-tree-15-dfs-12/</link><pubDate>Fri, 31 Jul 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-102-tree-15-dfs-12/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 102 Tree (15) / DFS (12)" /&gt;&lt;p&gt;&lt;strong&gt;1530. Number of Good Leaf Nodes Pairs (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&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;期限嘛&amp;hellip;就延長到滿人數吧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/advleetcode" target="_blank" rel="noopener"
&gt;https://bit.ly/advleetcode&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「從Leetcode學演算法」全套(基礎/進階/面試篇)同捆優惠：&lt;/strong&gt;&lt;br&gt;
&lt;a class="link" href="https://bit.ly/allleetcode" target="_blank" rel="noopener"
&gt;https://bit.ly/allleetcode&lt;/a&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 and an integer &lt;code&gt;distance&lt;/code&gt;. A pair of two different &lt;strong&gt;leaf&lt;/strong&gt; nodes of a binary tree is said to be good if the length of ** the shortest path** between them is less than or equal to &lt;code&gt;distance&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Return &lt;em&gt;the number of good leaf node pairs&lt;/em&gt; in the tree.&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-102-tree-15-dfs-12/image-001.png"
width="321"
height="321"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-102-tree-15-dfs-12/image-001_hu_d2d5b2f46fe0401a.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-102-tree-15-dfs-12/image-001_hu_dd2ba4b6efd9cc66.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="100"
data-flex-basis="240px"
&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: root = [1,2,3,null,4], distance = 3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: The leaf nodes of the tree are 3 and 4 and the length of the shortest path between them is 3. This is the only good pair.
&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;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-102-tree-15-dfs-12/image-002.png"
width="441"
height="321"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-102-tree-15-dfs-12/image-002_hu_c32ae8ce3cf43f3d.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-102-tree-15-dfs-12/image-002_hu_3bf6b4923ab43368.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="137"
data-flex-basis="329px"
&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: root = [1,2,3,4,5,6,7], distance = 3
&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: The good pairs are [4,5] and [6,7] with shortest path = 2. The pair [4,6] is not good because the length of ther shortest path between them is 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;h3 id="example-3"&gt;Example 3
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: root = [7,1,4,6,null,5,3,null,null,null,null,null,2], distance = 3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: The only good pair is [2,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;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: root = [100], distance = 1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 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;h3 id="example-5"&gt;Example 5
&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: root = [1,1,1], distance = 2
&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;The number of nodes in the &lt;code&gt;tree&lt;/code&gt; is in the range &lt;code&gt;[1, 2^10].&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Each node’s value is between &lt;code&gt;[1, 100]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1 &amp;lt;= distance &amp;lt;= 10&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;這題是2020/07/26舉辦的199th LeetCode Weekly Contest的第3題。&lt;br&gt;
給定一個二元樹的根節點root和一個整數距離distance，&lt;br&gt;
如果兩個不同的葉節點配對，其最小距離小於等於distance，&lt;br&gt;
我們就將其稱之為好(good)。&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;br&gt;
節點數量是1~2¹⁰，由於&lt;strong&gt;2¹⁰=1024&lt;/strong&gt; ，所以最壞的狀況，&lt;br&gt;
遞迴的數量也就1024而已，所以應該可以不會超過call stack的上限。&lt;br&gt;
接著，1≤distance≤10決定了我們在遞迴時，&lt;br&gt;
可以適度修剪我們要處理的節點。&lt;/p&gt;
&lt;p&gt;那這題該怎麼思考呢？&lt;br&gt;
由於我們在求的是最短距離，假定我們要看兩個節點x, y，&lt;br&gt;
那麼&lt;strong&gt;最短路徑肯定是從x往上走到x, y的最低共同祖先，&lt;br&gt;
再往下走到y的位置&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如果我們知道x, y的LCA(最低共同祖先)n，&lt;br&gt;
又知道n的左子樹的所有葉節點各自的深度，&lt;br&gt;
及右子樹的所有葉節點各自的深度，&lt;br&gt;
那麼我們就可以知道以n為LCA時，正確的節點對有哪些。&lt;br&gt;
怎麼知道？就迴圈加起來就好了嘛！&lt;/p&gt;
&lt;p&gt;那我們又怎麼知道某個節點n的左右子樹的葉節點深度呢？&lt;br&gt;
我們可以先用dfs往深處走，走到出現葉節點的時候，&lt;br&gt;
將其記錄為距離1並往上傳(因為這時候左右也都沒得走了)；&lt;/p&gt;
&lt;p&gt;那在某個非葉節點的&lt;strong&gt;n&lt;/strong&gt; 時，我們應該可以從dfs的結果，&lt;br&gt;
分別獲得&lt;strong&gt;左右子樹的各個葉節點離n的距離&lt;/strong&gt; 。&lt;br&gt;
我們將兩個距離的列表分別叫作&lt;strong&gt;llt跟rlt&lt;/strong&gt; (left list, right list)，&lt;br&gt;
從llt跟rlt分別成對取出來相加，&lt;br&gt;
每發現一組葉節點距離相加&lt;strong&gt;小於等於10，全局的解就加1&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;做完檢查以後該做什麼呢？&lt;br&gt;
裡面所有的葉節點應該可以往上通用，對吧？&lt;br&gt;
可是我們左子樹和右子樹往上都導到當前的節點再往上，&lt;br&gt;
&lt;strong&gt;再往上的深度應該都要加1&lt;/strong&gt; 才對！&lt;br&gt;
所以我們應該將llt和rlt裡面的所有值都分別+1以後，&lt;br&gt;
&lt;strong&gt;放入一個新的list，這裡命名為merge，再將其往上傳。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;因此，整個流程會大致如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;定一個class變數cnt，用來記錄成功配對的葉節點對的總數&lt;/li&gt;
&lt;li&gt;在主函式裡，先檢查root是否為NIL，是的話直接回傳0&lt;/li&gt;
&lt;li&gt;將root和distance帶入遞迴函式dfs中&lt;/li&gt;
&lt;li&gt;回傳cnt&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;而在dfs函式中，我們要做的事情是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;若n為NIL，回傳空的串列&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;若&lt;strong&gt;n的左右節點均為NIL&lt;/strong&gt; ，則回傳一個&lt;strong&gt;裡面只含一個1的串列&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;呼叫&lt;strong&gt;dfs(n.left, distance)&lt;/strong&gt; 及&lt;strong&gt;dfs(n.right, distance)&lt;/strong&gt; 進行遞迴，&lt;br&gt;
取得回傳的&lt;strong&gt;llt&lt;/strong&gt; 跟&lt;strong&gt;rlt&lt;/strong&gt; (記錄兩邊葉節點深度的串列)&lt;/li&gt;
&lt;li&gt;初始化一個空的串列&lt;strong&gt;merge&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;雙重迴圈，每當遇到llt和rlt的値**，&lt;br&gt;
兩兩相加會小於等於distance&lt;strong&gt;的狀況，就將&lt;/strong&gt; cnt遞增1**&lt;/li&gt;
&lt;li&gt;分別將llt和rlt的値全數+1後，&lt;strong&gt;加到merge&lt;/strong&gt; 裡&lt;br&gt;
(這邊可以檢查&lt;strong&gt;值必須小於distance&lt;/strong&gt; ，超過的話因為&lt;strong&gt;總路徑肯定超過，&lt;/strong&gt; 所以不符的不用放到merge內)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;回傳merge&lt;/strong&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;由於需要一個一個取出，並且重複使用，&lt;br&gt;
所以我們使用&lt;strong&gt;ArrayList&lt;/strong&gt; 並使用&lt;strong&gt;get&lt;/strong&gt; 來取得當中的值。&lt;br&gt;
在雙重迴圈的時候，我們可以&lt;strong&gt;順便將外層的値處理一下放到merge內&lt;/strong&gt; ，&lt;br&gt;
這樣後面就不用再重複一個新的迴圈處理。&lt;br&gt;
&lt;strong&gt;(但內層的不能這麼做，因為會被重複執行)&lt;/strong&gt;&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/0d13365f3b888363162a345bf51f0fe6.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分，cnt的累計可以使用list comprehension，&lt;br&gt;
&lt;strong&gt;處理符合的配對再來取len()&lt;/strong&gt; ，這樣寫起來會比雙重迴圈方便許多。&lt;br&gt;
llt和rlt則可以用類似的方式，最後將串列用加號組起來回傳。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/22ee498949dc5de4760ee139d546431e.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O((log N)³)/O(log N)，因為只有葉節點需要被記錄，&lt;br&gt;
空間應該跟最底層的節點數有關，而除了雙重迴圈外，&lt;br&gt;
dfs的深度也跟這棵樹的深度有關，但這個部分會受到distance的制約，&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;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學演算法 - 99 Tree (14) / DFS (11)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-99-tree-14-dfs-11/</link><pubDate>Mon, 13 Jul 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-99-tree-14-dfs-11/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 99 Tree (14) / DFS (11)" /&gt;&lt;p&gt;&lt;strong&gt;0404. Sum of Left Leaves (Easy)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&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/advleetcode" target="_blank" rel="noopener"
&gt;https://bit.ly/advleetcode&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「從Leetcode學演算法」全套(基礎/進階/面試篇)同捆優惠：&lt;/strong&gt;&lt;br&gt;
&lt;a class="link" href="https://bit.ly/allleetcode" target="_blank" rel="noopener"
&gt;https://bit.ly/allleetcode&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Find the sum of all left leaves in a given binary tree.&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;/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; 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; 9 20
&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; 15 7
&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;There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24.
&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;/p&gt;
&lt;p&gt;我們很久以前有提過二元樹的定義，&lt;br&gt;
忘記的話，請再複習一下XD&lt;br&gt;
&lt;strong&gt;而葉子的定義，就是它左右都沒有連接節點(NIL)！&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;這時候，你可能會說：&lt;br&gt;
我知道，那我只要一直往左邊看就好啦！&lt;/p&gt;
&lt;p&gt;呃&amp;hellip;&amp;hellip;同學，你忘記了你的&lt;strong&gt;右子樹也可能產生左葉子&lt;/strong&gt; 嗎XD？&lt;br&gt;
範例中的15，不就是先從3的右節點20，&lt;br&gt;
再往左節點來到15所得到的嗎？&lt;/p&gt;
&lt;p&gt;那怎麼辦呢？&lt;br&gt;
所以我們在檢查所在節點是不是葉子的時候，&lt;br&gt;
還需要看看這個節點是不是&lt;strong&gt;從它的根節點往左邊走下來&lt;/strong&gt; 的。&lt;br&gt;
因此，我們可以每次分支往左右走，給出一個參數from，&lt;br&gt;
分別&lt;strong&gt;給往左子樹走的函式1，給右子樹走的函式-1&lt;/strong&gt; ，&lt;br&gt;
用來代表下一層的時候拿來判定是不是左葉子的前置依據。&lt;/p&gt;
&lt;p&gt;當我們看到from == 1且左右節點均為NIL時，&lt;br&gt;
就可以將當前的節點值回傳，&lt;br&gt;
否則的話，就繼續遞迴往下找底下子樹當中左葉的和。&lt;/p&gt;
&lt;p&gt;依此，寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分，每次先檢查root是否為null，&lt;br&gt;
接著我們的答案就用&lt;br&gt;
&lt;strong&gt;sumOfLeftLeaves(root.left, 1) + sumOfLeftLeaves(root.right, -1)&lt;/strong&gt;&lt;br&gt;
來取得。&lt;br&gt;
其他的寫法概念如前所述。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/b8babe98eabb5f320c2d4952787a4a89.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分寫一個子函式，因為這邊沒有用self，&lt;br&gt;
所以可以不用self.getSum來算。&lt;br&gt;
(也可以把add設定預設値-1，&lt;br&gt;
使用單個sumOfLeftLeaves來解此題，&lt;br&gt;
這個化簡方式很簡單，就留給讀者來練習看看XD)&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/24d3e49c96c5c0928d166dd35c6fbcaa.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N)/O(1)，因為要經過每個節點，&lt;br&gt;
而如果考慮call stack的話，&lt;br&gt;
空間複雜度會是O(depth of Tree))&lt;/p&gt;
&lt;h2 id="相似及延伸"&gt;相似及延伸
&lt;/h2&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-51-bst-4-94cd8fe956ac" target="_blank" rel="noopener"
&gt;0235. Lowest Common Ancestor of a Binary Search Tree (Easy)&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;
&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學演算法 - 98 Tree (13) / DFS (10)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-98-tree-13-dfs-10/</link><pubDate>Sat, 27 Jun 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-98-tree-13-dfs-10/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 98 Tree (13) / DFS (10)" /&gt;&lt;p&gt;&lt;strong&gt;0129. Sum Root to Leaf Numbers (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&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/advleetcode" target="_blank" rel="noopener"
&gt;https://bit.ly/advleetcode&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「從Leetcode學演算法」全套(基礎/進階/面試篇)同捆優惠：&lt;/strong&gt;&lt;br&gt;
&lt;a class="link" href="https://bit.ly/allleetcode" target="_blank" rel="noopener"
&gt;https://bit.ly/allleetcode&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a binary tree containing digits from &lt;code&gt;0-9&lt;/code&gt; only, each root-to-leaf path could represent a number.&lt;/p&gt;
&lt;p&gt;An example is the root-to-leaf path &lt;code&gt;1-&amp;gt;2-&amp;gt;3&lt;/code&gt; which represents the number &lt;code&gt;123&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Find the total sum of all root-to-leaf numbers.&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;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;/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]
&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; / \
&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;Output: 25
&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;The root-to-leaf path 1-&amp;gt;2 represents the number 12.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;The root-to-leaf path 1-&amp;gt;3 represents the number 13.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Therefore, sum = 12 + 13 = 25.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-2"&gt;Example 2
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt; 1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt; 2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt; 3
&lt;/span&gt;&lt;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: [4,9,0,5,1]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 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; 9 0
&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 1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 1026
&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;The root-to-leaf path 4-&amp;gt;9-&amp;gt;5 represents the number 495.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;The root-to-leaf path 4-&amp;gt;9-&amp;gt;1 represents the number 491.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;The root-to-leaf path 4-&amp;gt;0 represents the number 40.
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Therefore, sum = 495 + 491 + 40 = 1026.
&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，&lt;br&gt;
每個根到葉子的路徑可以表達一個數。&lt;br&gt;
舉例來說，1-&amp;gt;2-&amp;gt;3可以表達123。&lt;br&gt;
找出所有的根到葉的數字的總和。&lt;br&gt;
(葉的定義是沒有子節點的節點)&lt;/p&gt;
&lt;p&gt;這題雖然標註為Medium，但其實並不那麼難思考，&lt;br&gt;
只是定義要弄清楚而已。&lt;/p&gt;
&lt;p&gt;首先，假設我們在某個節點n，它如果左節點和右節點都沒有的話，&lt;br&gt;
意味著它是葉(leaf)，這時數字就要計入總和；&lt;br&gt;
如果有其中一個成立的話，我們應該要往下走，&lt;br&gt;
並記錄之前經過的節點値，這樣子在遇到葉的時候才能夠結算。&lt;/p&gt;
&lt;p&gt;那麼自然，由於每棵樹只有0~9，&lt;br&gt;
所以從一層樹到下一層的時候，原先經過的數字的作用會放大10倍。&lt;br&gt;
也就是說，從上一層下來的時候，如果所在是葉的話，&lt;br&gt;
我們應該要把這個數字&lt;strong&gt;乘以10以後，加上現在的節點値&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;因此，我們只要遍歷完整棵樹，&lt;strong&gt;將葉子加總&lt;/strong&gt; 起來即可。&lt;br&gt;
寫成流程應該如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;檢查根節點是否為NIL，如果是，直接回傳0(此路不通)&lt;/li&gt;
&lt;li&gt;計算上面下來的值(last)到當前根節點的值(now)的結果，&lt;br&gt;
&lt;strong&gt;now = last * 10 + root.val&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;如果左右節點均為NIL，直接回傳&lt;strong&gt;now&lt;/strong&gt; 即可(當前節點為葉)&lt;/li&gt;
&lt;li&gt;將&lt;strong&gt;root.left, now及root.right, now&lt;/strong&gt; 分別傳入做遞迴計算&lt;strong&gt;左右子樹的和&lt;/strong&gt; ，&lt;br&gt;
最後&lt;strong&gt;加總起來並回傳&lt;/strong&gt; 。&lt;/li&gt;
&lt;li&gt;所以我們會先沿著最左邊一路到最底，然後依序將所有節點走過，&lt;br&gt;
這樣子是先往深處走，所以是所謂的深度優先搜尋(DFS)的方法。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;另外一方面，留意由於我們最開始已經檢查了root是否為NIL，&lt;br&gt;
所以在傳入左右子節點時，可以讓前面這條檢查來確認NIL的狀況，&lt;br&gt;
也就不用再先檢查節點是否為空了。&lt;/p&gt;
&lt;p&gt;依此，寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java可以使用相同的函式名稱，&lt;strong&gt;傳入不同長度的參數&lt;/strong&gt; 來處理。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/956fb2f701ae5495dea4e301a4b5fcd0.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分，我們直接&lt;strong&gt;設定預設值&lt;/strong&gt; ，這樣就可以通用了XD&lt;br&gt;
當從根節點開始時，由於只傳入root, 自然last會是0。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/bebba246f6dd601d4698ad348c08153c.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N)/O(1), 如果算上call stack的部分的話，&lt;br&gt;
平均空間複雜度是O(logN) (DFS的深度))&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學演算法 - 96 BST (5) / DFS (10)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-96-bst-5-dfs-10/</link><pubDate>Tue, 09 Jun 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-96-bst-5-dfs-10/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 96 BST (5) / DFS (10)" /&gt;&lt;p&gt;&lt;strong&gt;1008. Construct Binary Search Tree from Preorder Traversal (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="寫在前面"&gt;寫在前面
&lt;/h2&gt;&lt;p&gt;容筆者工商一下，&lt;br&gt;
&lt;strong&gt;「從Leetcode學演算法｜進階篇」在今天(6/9)中午12點&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://hiskio.com/packages/YoRY45yZm" target="_blank" rel="noopener"
&gt;https://hiskio.com/packages/YoRY45yZm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;「從Leetcode學演算法」全套(基礎/進階/面試篇)同捆優惠：&lt;/strong&gt;&lt;br&gt;
&lt;a class="link" href="https://hiskio.com/packages/MByQ4pw3W" target="_blank" rel="noopener"
&gt;https://hiskio.com/packages/MByQ4pw3W&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;另外，&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Return the root node of a binary &lt;strong&gt;search&lt;/strong&gt; tree that matches the given &lt;code&gt;preorder&lt;/code&gt; traversal.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(Recall that a binary search tree is a binary tree where for every node, any descendant of&lt;/em&gt; &lt;code&gt;node.left&lt;/code&gt; &lt;em&gt;has a value&lt;/em&gt; &lt;code&gt;&amp;lt;``node.val&lt;/code&gt;&lt;em&gt;, and any descendant of&lt;/em&gt; &lt;code&gt;node.right&lt;/code&gt; &lt;em&gt;has a value&lt;/em&gt; &lt;code&gt;&amp;gt;``node.val&lt;/code&gt;&lt;em&gt;. Also recall that a preorder traversal displays the value of the&lt;/em&gt; &lt;code&gt;node&lt;/code&gt; &lt;em&gt;first, then traverses&lt;/em&gt; &lt;code&gt;node.left&lt;/code&gt;&lt;em&gt;, then traverses&lt;/em&gt; &lt;code&gt;node.right&lt;/code&gt;&lt;em&gt;.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;It’s guaranteed that for the given test cases there is always possible to find a binary search tree with the given requirements.&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: [8,5,1,7,10,12]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [8,5,10,1,7,null,12]
&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-96-bst-5-dfs-10/0_onS6QbVL4p9hvos1.png"
width="590"
height="386"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-96-bst-5-dfs-10/0_onS6QbVL4p9hvos1_hu_7d02e4500993eee8.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-96-bst-5-dfs-10/0_onS6QbVL4p9hvos1_hu_15ef9a45075a191d.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="152"
data-flex-basis="366px"
&gt;&lt;/p&gt;
&lt;h3 id="constraints"&gt;Constraints
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;1 &amp;lt;= preorder.length &amp;lt;= 100&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;1 &amp;lt;= preorder[i] &amp;lt;= 10^8&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The values of &lt;code&gt;preorder&lt;/code&gt; are distinct.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;從給定的&lt;strong&gt;前序走訪&lt;/strong&gt; 一棵二元搜尋樹的結果，&lt;br&gt;
重建一棵符合的二元搜尋樹，並回傳其根節點。&lt;br&gt;
題目給出的測試資料均保證可以找到一個符合的二元搜尋樹。&lt;/p&gt;
&lt;p&gt;我們很早以前已經解說過&lt;strong&gt;二元搜尋樹的特性&lt;/strong&gt; 了，&lt;br&gt;
&lt;strong&gt;前序走訪(preorder)&lt;/strong&gt; 表示順序是&lt;strong&gt;根-左-右&lt;/strong&gt; ，&lt;br&gt;
不像是&lt;strong&gt;中序走訪(inorder)&lt;/strong&gt; 會剛好是&lt;strong&gt;左-根-右，順序會剛好由小到大排列&lt;/strong&gt; 。&lt;br&gt;
那麼，我們要怎麼樣才能架構一個合理的BST(二元搜尋樹)呢？&lt;br&gt;
由於BST和preorder的特性，當我們一路往左走的時候，&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;/p&gt;
&lt;p&gt;如果我們當下碰到了比根節點還要大的狀況呢？&lt;br&gt;
代表這段往左已經走完了，現在看到的是右節點。&lt;br&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;br&gt;
反之，則代表它應該&lt;strong&gt;在上一層或更上層&lt;/strong&gt; 才對。&lt;br&gt;
此外，我們可以設定一個class的變數i，&lt;br&gt;
用來紀錄現在我們建立二元樹的過程走到哪個index。&lt;/p&gt;
&lt;p&gt;那麼我們來整理一下流程：&lt;br&gt;
0. 初始化一個class變數 &lt;strong&gt;i = 0&lt;/strong&gt; 。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先檢查當前的陣列/串列是不是&lt;strong&gt;沒東西&lt;/strong&gt; ，沒東西的話就回傳null/None。&lt;/li&gt;
&lt;li&gt;將&lt;strong&gt;int的最大值&lt;/strong&gt; 作為&lt;strong&gt;邊界值&lt;/strong&gt; bound，&lt;br&gt;
傳入用來建立二元樹的函式(這裡命名為&lt;strong&gt;build&lt;/strong&gt; )&lt;/li&gt;
&lt;li&gt;在build函式中，檢查如果&lt;strong&gt;i走完全長了&lt;/strong&gt; 或者&lt;strong&gt;preorder[i] &amp;gt; bound，&lt;br&gt;
前者表示整個樹重建完了，後者表示這個子樹底下對於preorder[i]來說不可能放在任何一個地方了，所以回傳null/None回到上一層。&lt;strong&gt;4. 在這層建立一個&lt;/strong&gt; 根節點root&lt;/strong&gt;，** 其值為preorder[i]&lt;strong&gt;，完成後&lt;/strong&gt; 將i遞增**。&lt;/li&gt;
&lt;li&gt;接下來要建立root.left，呼叫build函式，&lt;br&gt;
將preorder&lt;strong&gt;及邊界值root.val&lt;/strong&gt; 傳入。&lt;br&gt;
(因為root的左子樹所有值都要小於root的值)&lt;/li&gt;
&lt;li&gt;再來建立root.right，呼叫build函式，&lt;br&gt;
將preorder及邊界值bound傳入。&lt;br&gt;
(因為root的右子樹裡的所有值要介於&lt;strong&gt;root的值&lt;/strong&gt; 和&lt;strong&gt;上一層限制的bound&lt;/strong&gt; 之間)&lt;/li&gt;
&lt;li&gt;這層等於建立完畢了，&lt;strong&gt;將root回傳&lt;/strong&gt; 。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我們簡單拿Example 1為範例來嘗試推導看看：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;(i, preorder[i], bound) = (0, 8, Integer.MAX_VALUE)&lt;br&gt;
=&amp;gt; root節點建立，其值為8，i遞增，呼叫build(preorder, 8)以建立左節點。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(i, preorder[i], bound) = (1, 5, 8)&lt;br&gt;
=&amp;gt; 建立根節點，其值為5，i遞增，呼叫build(preorder, 5)以建立左節點。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(i, preorder[i], bound) = (2, 1, 5)&lt;br&gt;
=&amp;gt; 建立根節點，其值為1，i遞增，呼叫build(preorder, 1)以建立左節點。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(i, preorder[i], bound) = (3, 7, 1)&lt;br&gt;
=&amp;gt; 7&amp;gt;1，所以表示這層沒辦法放了，回傳null到上一層。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(i, preorder[i], bound) = (3, 7, 5)&lt;br&gt;
=&amp;gt; 走到root.right這行，呼叫build(preorder, 8)以建立右節點。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(i, preorder[i], bound) = (3, 7, 8)&lt;br&gt;
=&amp;gt; 建立根節點，其值為7，i遞增，&lt;br&gt;
呼叫root.left及root.right兩行都會回傳null，&lt;br&gt;
所以回傳該節點到上一層。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(i, preorder[i], bound) = (4, 10, 8)&lt;br&gt;
=&amp;gt; 在5的底下建立完7的右節點了，這邊也完成了，&lt;br&gt;
回傳5的節點回到上一層。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(i, preorder[i], bound) = (4, 10, Integer.MAX_VALUE)&lt;br&gt;
=&amp;gt; 走到root.right這行，呼叫build(preorder, Integer.MAX_VALUE)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(i, preorder[i], bound) = (4, 10, Integer.MAX_VALUE)&lt;br&gt;
=&amp;gt; 建立根節點，其值為10，i遞增，&lt;br&gt;
root.left這行會回傳null，&lt;br&gt;
root.right傳入build(preorder, Integer.MAX_VALUE)。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;(i, preorder[i], bound) = (5, 12, Integer.MAX_VALUE)&lt;br&gt;
=&amp;gt; 建立根節點，其值為12，i遞增。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;後面的部分由於i已經到達6，所以會往上層回到8的這層，&lt;br&gt;
最後回傳根節點(值為8)，結束。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;請讀者嘗試在紙上畫出來推過一遍，有助於更了解整個程式運行。&lt;br&gt;
由於我們是先一路往左深入並建立節點，碰到無法建立時，&lt;br&gt;
才回到上一層並嘗試往右走，&lt;br&gt;
所以這樣子的方式是&lt;strong&gt;DFS(深度優先搜尋)&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的部分，&lt;br&gt;
使用int時可以用Integer.MAX_VALUE作為初始邊界(即int能表示的最大值)。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/39b4b56e6af4cda414fbe3fdc93fa9a3.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分，我們可以設定bound在未傳入值時預設值當作&lt;strong&gt;float(&amp;lsquo;inf&amp;rsquo;)&lt;/strong&gt; ，&lt;br&gt;
即可使用同一個函式進行遞迴。&lt;br&gt;
此外，還是不要忘記Python並沒有++或&amp;ndash;，請自己換成用**”self.i += 1&amp;quot;** 。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/751f9e2e2f88ba60f6d45a2708341330.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(length of array)/O(1), 如果計算call stack的話則是O(BST的深度))&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;另外，「從Leetcode學演算法｜基礎篇」已經回原價囉，&lt;br&gt;
先前的優惠碼會失效，但這邊仍然為讀者保留了300塊的折抵，&lt;br&gt;
雖然整捆一起買總體比較划算(差290而已就有整組了阿XD)，&lt;br&gt;
如果你還是想先試試基礎課的話，&lt;br&gt;
&lt;strong&gt;300元折抵的連結&lt;/strong&gt; 在這邊： &lt;a class="link" href="https://hiskio.com/courses/319?promo_code=NEXLJXE" target="_blank" rel="noopener"
&gt;https://hiskio.com/courses/319?promo_code=NEXLJXE&lt;/a&gt;&lt;/p&gt;</description></item><item><title>從LeetCode學演算法 - 93 Tree (12) / DFS (9)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-93-tree-12-dfs-9/</link><pubDate>Sun, 10 May 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-93-tree-12-dfs-9/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 93 Tree (12) / DFS (9)" /&gt;&lt;p&gt;&lt;strong&gt;0687. Longest Univalue Path (Easy)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a binary tree, find the length of the longest path where each node in the path has the same value. This path may or may not pass through the root.&lt;/p&gt;
&lt;p&gt;The length of the path between two nodes is represented by the number of edges between them.&lt;/p&gt;
&lt;h3 id="example-1"&gt;Example 1
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Input:&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;/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 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; 1 1 5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt; 2&lt;/p&gt;
&lt;h3 id="example-2"&gt;Example 2
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Input:&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;/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; 4 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 4 5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt; 2&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The given binary tree has not more than 10000 nodes. The height of the tree is not more than 1000.&lt;/p&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一個二元樹，尋找其最長的路徑長，&lt;br&gt;
當中的所有節點必須擁有相同的值。&lt;br&gt;
這條路徑通過或沒有通過根節點均可。&lt;br&gt;
(路徑長度的定義為兩個節點之間經過的邊(edge)的數量)&lt;/p&gt;
&lt;p&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-13-tree-1-52cfbdde02b2" target="_blank" rel="noopener"
&gt;0100. Same Tree&lt;/a&gt;)，&lt;br&gt;
在此就不再贅述。這題嘗試要找相同值的路徑，&lt;br&gt;
但又不限定要通過root，該怎麼思考呢？&lt;br&gt;
我們可以先考慮怎樣可以算&lt;strong&gt;一條相同值的路徑&lt;/strong&gt; 。&lt;br&gt;
一條相同值的路徑有可能有以下兩種狀況：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;從一個頂點下來，&lt;br&gt;
每次選擇往左節點走或往右節點走，到一個位置停下。&lt;br&gt;
例如：&lt;/li&gt;
&lt;/ol&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; 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 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; 1 1 5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;當中的5-5-5就是一條相同值的路徑。&lt;/p&gt;
&lt;ol start="2"&gt;
&lt;li&gt;從一個頂點進行分岔，左右各自走到一個位置停下。&lt;br&gt;
例如：&lt;/li&gt;
&lt;/ol&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;　　　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; 4 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 4 5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;當中的&lt;strong&gt;粗斜體的4-4-4&lt;/strong&gt; 就是一條從頂點往左右分岔所得到的路徑，&lt;br&gt;
可以選擇從&lt;strong&gt;左下的4 -&amp;gt; 中間的4 -&amp;gt; 再到右邊的4&lt;/strong&gt; ，這樣連成一個路徑。&lt;br&gt;
但從這邊來看可以發現，這條路徑就無法把root的4算在內，&lt;br&gt;
&lt;strong&gt;因為不管怎麼連，我們都沒辦法一筆不重複將這4個4走完。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;因此，我們可以得知：&lt;br&gt;
對於某個節點來說，有經過它所能得到的最長路徑，&lt;br&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;br&gt;
第二個情況來說，則要將&lt;strong&gt;左右和它的值相同的路徑長相加&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;所以我們可以定義一個count函式，&lt;br&gt;
回傳以某個節點值來說，其下的最長所能得到的相同值的路徑長，&lt;br&gt;
當中計算的時候一邊留意當下最長的路徑長並進行更新。&lt;/p&gt;
&lt;p&gt;我們將整個題目的答案(相同值的最長路徑長)叫做mx(叫result也可以)，&lt;br&gt;
&lt;strong&gt;流程順序應為：&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;一開始應該先&lt;strong&gt;檢查root是否為NIL&lt;/strong&gt; ，&lt;br&gt;
如是，回傳&lt;strong&gt;0&lt;/strong&gt; (因為沒有路徑)，否則呼叫count函式，&lt;br&gt;
&lt;strong&gt;檢查它所能得到的相同值的最長路徑長&lt;/strong&gt; 。&lt;br&gt;
(傳入root節點，及當下的&lt;strong&gt;路徑節點值root.val&lt;/strong&gt; )&lt;/li&gt;
&lt;li&gt;在count當中，&lt;br&gt;
同樣應先檢查傳入的節點值是否為null，&lt;br&gt;
接下來為了要知道左右路徑的相同值的最長路徑長，&lt;br&gt;
應該要分別帶入其&lt;strong&gt;left/right節點及當前節點的值&lt;/strong&gt; 進去檢查，&lt;br&gt;
假設得到的結果分別為&lt;strong&gt;l/r&lt;/strong&gt; 。&lt;/li&gt;
&lt;li&gt;依照2的定義，l + r的值代表了一條可能的相同值路徑，&lt;br&gt;
所以要拿它和mx比較，將較長的路徑值更新。&lt;/li&gt;
&lt;li&gt;如果&lt;strong&gt;當前的節點值&lt;/strong&gt; 和**傳進來的路徑節點值兩者相同，&lt;br&gt;
代表有機會可以考慮上面提到過的&lt;br&gt;
「&lt;strong&gt;從一個頂點下來，每次選擇往左節點走或往右節點走，&lt;br&gt;
到一個位置停下。&lt;/strong&gt;」的狀況，&lt;br&gt;
這時候要回傳的值會是左右路徑長較長的部分+1。&lt;br&gt;
(因為要包含左節點/右節點到當前節點的這個路徑)&lt;/li&gt;
&lt;li&gt;上面的判斷不成立的話，代表路徑從上面下來到這邊斷掉了。&lt;br&gt;
(值不相同)，這時候應該回傳0，代表相同值路徑到這邊沒辦法繼續。**&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;上面的流程順序，請讀者務必自行畫圖推導，&lt;br&gt;
會比較清楚整個思考過程。&lt;/p&gt;
&lt;p&gt;依此，寫成程式碼如下：&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;p&gt;Java的部分mx直接宣告一個class變數即可，其它就是使用Math.max，&lt;br&gt;
及檢查null的部分，並不複雜。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/08af5452682a0112c7484b118310a12e.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的話，可以使用self.mx來宣告，&lt;br&gt;
並且在__init__時進行處理，&lt;br&gt;
其它就是一樣注意呼叫時不要忘記用&lt;strong&gt;self&lt;/strong&gt; 即可。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/2de59e38d37647b769952cc56f3fa375.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N)/O(1)，如果空間要算上call stack的部分的話，&lt;br&gt;
則是O(TreeNode的高度)。)&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=VE9Q5VE" target="_blank" rel="noopener"
&gt;** https://hiskio.com/courses/319?promo_code=VE9Q5VE**&lt;/a&gt;&lt;/p&gt;</description></item><item><title>從LeetCode學演算法 - 90 Dynamic Programming (11) / DFS (9)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-90-dynamic-programming-11-dfs-9/</link><pubDate>Sun, 22 Mar 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-90-dynamic-programming-11-dfs-9/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 90 Dynamic Programming (11) / DFS (9)" /&gt;&lt;p&gt;&lt;strong&gt;0576. Out of Boundary Paths (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;There is an &lt;strong&gt;m&lt;/strong&gt; by ** n** grid with a ball. Given the start coordinate ** (i,j)** of the ball, you can move the ball to an ** adjacent** cell or cross the grid boundary in four directions (up, down, left, right). However, you can ** at most** move ** N** times. Find out the number of paths to move the ball out of the grid boundary. The answer may be very large, return it after mod 10⁹ + 7.&lt;/p&gt;
&lt;h3 id="example-1"&gt;Example 1
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: m = 2, n = 2, N = 2, i = 0, j = 0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 6
&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;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-90-dynamic-programming-11-dfs-9/image-001.png"
width="800"
height="473"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-90-dynamic-programming-11-dfs-9/image-001_hu_213c7b39062f876a.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-90-dynamic-programming-11-dfs-9/image-001_hu_9a760414bfacc3bc.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="169"
data-flex-basis="405px"
&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;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: m = 1, n = 3, N = 3, i = 0, j = 1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 12
&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;p&gt;&lt;img src="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-90-dynamic-programming-11-dfs-9/image-002.png"
width="756"
height="443"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-90-dynamic-programming-11-dfs-9/image-002_hu_da207eaa06da7ecb.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-90-dynamic-programming-11-dfs-9/image-002_hu_d3c59730ae8bf61d.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="170"
data-flex-basis="409px"
&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Once you move the ball out of the boundary, you cannot move it back.&lt;/li&gt;
&lt;li&gt;The length and height of the grid are in the range [1,50].&lt;/li&gt;
&lt;li&gt;N is in range [0,50].&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;題目描述有一組 m * n 的方格，格子上有一個球，其起始座標為 (i, j)，&lt;br&gt;
你可以將球移到四個方向內沒超過邊界的格子，但最多只能移動N次。&lt;br&gt;
試算出所有會將球移超過邊界的路徑數目。&lt;br&gt;
限制：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;一旦移出邊界就不能再回來(也就是直接遊戲結束了)&lt;/li&gt;
&lt;li&gt;格子的寬高均在1~50的範圍&lt;/li&gt;
&lt;li&gt;總次數N在0~50的範圍&lt;br&gt;
另由於答案可能非常大，回傳結果要先&lt;strong&gt;除以10的9次方+7。&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我們先思考關於路徑超過邊界的狀態。&lt;br&gt;
要被算做是其中一種的話，首先最後一步一定要是從&lt;strong&gt;格子內移到格子外&lt;/strong&gt; ，&lt;br&gt;
也就是要在邊界才可以，只差一格index就&lt;strong&gt;小於0&lt;/strong&gt; 或**&amp;gt;m-1** (或&lt;strong&gt;n-1&lt;/strong&gt; )。&lt;br&gt;
畢竟不在懸崖邊怎麼可能會有掉下懸崖的可能對吧XD！&lt;br&gt;
並且，因為&lt;strong&gt;掉下去就回不來了&lt;/strong&gt; ，所以路徑就會到此為止。&lt;br&gt;
(當然不管剩下的步數，你總不會飛簷走壁吧@@)&lt;/p&gt;
&lt;p&gt;接著，當 &lt;strong&gt;N=0&lt;/strong&gt; 時，&lt;br&gt;
&lt;strong&gt;由於根本沒辦法動，自然不會有符合的路徑&lt;/strong&gt; ，答案為0。&lt;br&gt;
&lt;strong&gt;N = 1&lt;/strong&gt; 時，則要** 看你四邊有幾個懸崖&lt;strong&gt;對吧！&lt;br&gt;
那N = 2呢？&lt;br&gt;
是不是就要先看&lt;/strong&gt;這一步有幾種可能會掉下去，加總起來以後** ，&lt;br&gt;
接下來&lt;strong&gt;先走到不會掉下去的地方，再看那幾個有幾種情況會掉下去。&lt;br&gt;
由於每走一步路，可用的步數就會少1&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;這個方式聽起來很DFS對吧？&lt;br&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;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;13
&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;# Will TLE
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;class Solution:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; def findPaths(self, m: int, n: int, N: int, i: int, j: int) -&amp;gt; int:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; def dfs(i, j, N):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; res = 0
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; if N != 0:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; res += 1 if i - 1 &amp;lt; 0 else dfs(i-1, j, N-1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; res += 1 if i + 1 == m else dfs(i+1, j, N-1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; res += 1 if j - 1 &amp;lt; 0 else dfs(i, j-1, N-1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; res += 1 if j + 1 == n else dfs(i, j+1, N-1)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; return res
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; res = dfs(i, j, N)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; return res % (10 ** 9 + 7)
&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;當方向會掉下去的時候，就代表方法數加1；&lt;br&gt;
否則的話，就要往那個方向走1步去算可能的方法。&lt;br&gt;
你會發現測試一般的結果可以算出正確答案，&lt;br&gt;
但大一點的數字會算到超時，為什麼呢？&lt;/p&gt;
&lt;p&gt;其實理由跟以前我們算Fibonacci數列時一樣，&lt;br&gt;
這樣子的寫法會導致每一個數都是從單一個1累加起來的，&lt;br&gt;
中間我們可能走到同樣的格子，剩下相同的步數，&lt;br&gt;
卻沒有利用到這點，從而導致效率超級差。&lt;/p&gt;
&lt;p&gt;那怎麼辦呢？&lt;br&gt;
當我們同時考慮動態規劃的觀念時，&lt;br&gt;
就容易想到，我們可以將先前算過的東西當成已知的內容儲存起來，&lt;br&gt;
當再碰到時，就可以直接取用計算。&lt;br&gt;
在本例當中，影響到結果的值有i, j, N，&lt;br&gt;
所以我們可以選擇使用&lt;strong&gt;一個三維的陣列/串列&lt;/strong&gt; ，(也可以用兩個二維陣列)&lt;br&gt;
或者Python內也可以用&lt;strong&gt;字典&lt;/strong&gt; 來做對應儲存。&lt;br&gt;
扣除掉這點以外，跟前面的寫法並無不同，讀者可以自行參照看看。&lt;/p&gt;
&lt;p&gt;那麼，有沒有別種思考的方式呢？&lt;br&gt;
有的，像是lee215就提供了另一種思路：&lt;br&gt;
我們最開始N=0時，整個盤面不論i, j為什麼，&lt;br&gt;
(i, j, 0)的結果都會是0，而(i, j, N)的結果，&lt;br&gt;
則取決於**(i, j)上下左右4格在N-1步的時候** 的結果。&lt;br&gt;
如果該格超出邊界，則至少從(i, j)有1步可以走出邊界，&lt;br&gt;
反之，(i, j)可以花1步走過去。&lt;br&gt;
因此，我們可以一次一次更新整個盤面，&lt;br&gt;
從而算得第N步的結果。(&lt;strong&gt;參見Python lee215解&lt;/strong&gt; )&lt;/p&gt;
&lt;p&gt;或者，我們也可以從i, j為起點，&lt;br&gt;
記錄從&lt;strong&gt;i, j到某一格的總路徑數量&lt;/strong&gt; ，&lt;br&gt;
&lt;strong&gt;每當有機會超出邊界時，則將該部分加總到結果中，&lt;br&gt;
兩個方法殊途同歸，最後都可以得到解答。(參見Java shawngao解)&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的部分，除了上面提過的遞進計算整個盤面，&lt;br&gt;
(使用兩個二維陣列交替)&lt;br&gt;
也可以用三維陣列去記錄結果，&lt;br&gt;
留意為了要偵測是否有記錄結果，&lt;br&gt;
我們要用Arrays.fill()，將初始化的陣列都填入-1，&lt;br&gt;
這樣我們才知道這個值它是0還是未填入的狀態。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/0f38d843a1cec840a22f7c2b6855078e.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分，除了lee215的解法外，&lt;br&gt;
我們也可以如上面提到的採用一個字典來進行儲存先前已計算過的內容。&lt;br&gt;
此外，由於在這個問題中，&lt;br&gt;
鏡像對稱位置的點在相同的N值下應該會有相同的答案，&lt;br&gt;
所以還可以透過對稱的方式來進一步化簡所需的計算數量。&lt;br&gt;
(可以看註解底下最後一個解，65~69行的部分)&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/c116a47b873399929e841da0e7b405b3.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(時間複雜度方面，原則上最壞的狀況就是每個步驟算完整個盤面，&lt;br&gt;
所以會是&lt;strong&gt;O(m*n*N)&lt;/strong&gt; 。&lt;br&gt;
空間複雜度的話，使用&lt;strong&gt;三維陣列或字典&lt;/strong&gt; 的話是&lt;strong&gt;O(m*n*N)&lt;/strong&gt; ，&lt;br&gt;
而使用&lt;strong&gt;兩個二維陣列交替記錄&lt;/strong&gt; 的話則是&lt;strong&gt;O(m*n)&lt;/strong&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=VE9Q5VE" target="_blank" rel="noopener"
&gt;** https://hiskio.com/courses/319?promo_code=VE9Q5VE**&lt;/a&gt;&lt;/p&gt;</description></item><item><title>從LeetCode學演算法 - 84 Tree (11) / DFS (8)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-84-tree-11-dfs-8/</link><pubDate>Fri, 24 Jan 2020 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-84-tree-11-dfs-8/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 84 Tree (11) / DFS (8)" /&gt;&lt;p&gt;&lt;strong&gt;0116. Populating Next Right Pointers in Each Node (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;You are given a &lt;strong&gt;perfect binary tree&lt;/strong&gt; where all leaves are on the same level, and every parent has two children. The binary tree has the following definition:&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;struct Node {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; int val;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Node *left;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Node *right;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Node *next;
&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;Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to &lt;code&gt;NULL&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Initially, all next pointers are set to &lt;code&gt;NULL&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Follow up:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You may only use constant extra space.&lt;/li&gt;
&lt;li&gt;Recursive approach is fine, you may assume implicit stack space does not count as extra space for this problem.&lt;/li&gt;
&lt;/ul&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-84-tree-11-dfs-8/image-001.png"
width="800"
height="273"
srcset="https://desolve.pages.dev/post/learn-algorithm-from-leetcode-84-tree-11-dfs-8/image-001_hu_3023d38a6e81834b.png 480w, https://desolve.pages.dev/post/learn-algorithm-from-leetcode-84-tree-11-dfs-8/image-001_hu_5cbd9b16c7852a62.png 1024w"
loading="lazy"
class="gallery-image"
data-flex-grow="293"
data-flex-basis="703px"
&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: root = [1,2,3,4,5,6,7]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: [1,#,2,3,#,4,5,6,7,#]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: Given the above perfect binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B. The serialized output is in level order as connected by the next pointers, with &amp;#39;#&amp;#39; signifying the end of each level.
&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;給定一個完美二元樹(perfect binary tree)，&lt;br&gt;
也就是所有葉子都在相同level且所有父節點均有兩個子節點。&lt;br&gt;
在Node的定義中增加一個next的定義，&lt;br&gt;
如圖所示，每個節點的next為其右邊的節點，&lt;br&gt;
如右邊已無節點，則為NULL。&lt;br&gt;
(最開始的時候預設所有節點的next均為NULL)&lt;br&gt;
請把整個next的定義完成。&lt;/p&gt;
&lt;p&gt;由於這個題目已經有提到說只能用常數的額外記憶體空間了，&lt;br&gt;
但同時將遞迴導致的stack(也就是call stack)當作不算，&lt;br&gt;
所以使用簡單的遞迴可以簡單達到目的。&lt;/p&gt;
&lt;p&gt;最直觀的方式，就是先檢查root是否是null，&lt;br&gt;
接下來呼叫一個helper function，代入左節點和右節點來處理，&lt;br&gt;
只要左節點不是NULL，則將左節點的next設為右節點；&lt;br&gt;
接下來則要分別處理這三個連接：&lt;br&gt;
&lt;strong&gt;1. 左節點的left -&amp;gt; 左節點的right&lt;br&gt;
2. 左節點的right -&amp;gt; 右節點的left&lt;br&gt;
3. 右節點的left -&amp;gt; 右節點的right&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;當然，也可以從root為中心出發，&lt;br&gt;
這時候每次要關注的應該是root.left -&amp;gt; root.right，&lt;br&gt;
及root.right -&amp;gt; root.next.left。&lt;/p&gt;
&lt;p&gt;如果想要用迭代的方式呢？&lt;br&gt;
我們留意到每次開始進行連接的都是當個階層的最左邊的節點，&lt;br&gt;
從&lt;strong&gt;Figure B&lt;/strong&gt; 上來看的話，即為1, 2, 4…等節點。&lt;br&gt;
所以我們最開始應該要從一個階層的最左邊的節點&lt;br&gt;
(這邊叫做level_first)開始進行迭代，將當前的節點稱為curr&lt;br&gt;
分別將&lt;strong&gt;curr.left -&amp;gt; curr.right&lt;/strong&gt; 及&lt;strong&gt;curr.right -&amp;gt; curr.next.left。&lt;br&gt;
接著讓curr遞移到curr.next。&lt;br&gt;
所以每次連接兩組next的關係，直到curr走到NULL為止。&lt;br&gt;
這時候這層走完以後，進行到下一層，&lt;br&gt;
level_first應該遞移到level_first.left。&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中，上述三種方法均有列出，&lt;br&gt;
順序剛好跟上面提到的相反，&lt;br&gt;
請務必留意在接續前必須要留意要確定節點是否為null的狀況。&lt;br&gt;
如果計入call stack的話，只有迭代的方式是O(1)才對。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/889bec573f69f5640c33455484b98209.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;p&gt;Python的部分大同小異，不要忘記使用self來呼叫，&lt;br&gt;
這邊僅列出第二種和第三種。&lt;/p&gt;
&lt;script src="https://gist.github.com/Desolve/58b0d724cf6dc9a63281d6eb428989b2.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N)/O(1)，如果不考慮Call Stack的話。&lt;br&gt;
如果考慮的話上面只有直接使用迴圈迭代的是O(1))&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=VE9Q5VE" target="_blank" rel="noopener"
&gt;** https://hiskio.com/courses/319?promo_code=VE9Q5VE**&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學演算法 - 55 DFS (3)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-55-dfs-3/</link><pubDate>Mon, 23 Sep 2019 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-55-dfs-3/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 55 DFS (3)" /&gt;&lt;p&gt;&lt;strong&gt;0236. Lowest Common Ancestor of a Binary Tree (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 binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.&lt;/p&gt;
&lt;p&gt;According to the &lt;a class="link" href="https://en.wikipedia.org/wiki/Lowest_common_ancestor" target="_blank" rel="noopener"
&gt;definition of LCA on Wikipedia&lt;/a&gt;: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow &lt;strong&gt;a node to be a descendant of itself&lt;/strong&gt; ).”&lt;/p&gt;
&lt;p&gt;Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]&lt;/p&gt;
&lt;p&gt;&lt;img src="https://desolve.pages.dev/image-001.png"
loading="lazy"
&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;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: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: The LCA of nodes 5 and 1 is 3.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="example-2"&gt;Example 2
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Output: 5
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All of the nodes’ values will be unique.&lt;/li&gt;
&lt;li&gt;p and q are different and both values will exist in the binary tree.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="分析解題"&gt;分析/解題
&lt;/h3&gt;&lt;p&gt;給定一棵二元樹，試找出樹中兩個給定的節點的最低共同祖先(LCA)。&lt;br&gt;
整棵樹的節點值均不同，且兩個節點p, q是不同的節點，&lt;br&gt;
且會存在於此樹上。&lt;/p&gt;
&lt;p&gt;由於不同於之前的&lt;a class="link" href="../learn-algorithm-from-leetcode-51-bst-4" &gt;0235&lt;/a&gt;題，這題是二元樹而非二元搜尋樹，&lt;br&gt;
所以我們於此喪失了可以透過比大小來決定要往哪個方向走的可能。&lt;br&gt;
那麼怎麼辦呢？&lt;/p&gt;
&lt;p&gt;對於兩個節點的最低共同祖先來說，有一個特性是絕對肯定的，&lt;br&gt;
就是以下3點必然會&lt;strong&gt;恰好成立2點&lt;/strong&gt; ：&lt;br&gt;
&lt;strong&gt;1. 節點自己是p或q&lt;br&gt;
2. 節點的左子樹有p或q&lt;br&gt;
3. 節點的右子樹有p或q&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1, 2和1, 3應該很直觀，就不多作解釋了，&lt;br&gt;
這邊有一點很重要的是，&lt;strong&gt;當共同祖先不是p或q&lt;/strong&gt; 的時候，&lt;br&gt;
如果&lt;strong&gt;p和q都分布在同一邊的子樹，那它就不會是最低共同祖先&lt;/strong&gt; ，&lt;br&gt;
因為我們還可以再往下找更低的共同祖先。&lt;br&gt;
所以&lt;strong&gt;1不成立的時候，2, 3都必須要成立才行&lt;/strong&gt; ，&lt;br&gt;
這樣才能符合&lt;strong&gt;最低&lt;/strong&gt; 的特性。&lt;/p&gt;
&lt;p&gt;我們可以運用&lt;strong&gt;DFS&lt;/strong&gt; 的方式來確認一個節點的左子樹/右子樹是否符合特性，&lt;br&gt;
並且&lt;strong&gt;同時判斷該節點是否是p或q之一&lt;/strong&gt; ，&lt;br&gt;
這樣一來，只要&lt;strong&gt;三者成立兩點&lt;/strong&gt; 的時候，就表示我們找到目標了，&lt;br&gt;
可以將答案記錄下來。&lt;/p&gt;
&lt;p&gt;所以只要將整棵樹遍歷過一次，最後回傳記錄下來的答案即可。&lt;br&gt;
實作上，我們將1當作成立，0當作不成立，&lt;br&gt;
那麼整個DFS的過程就是在找三個結果相加等於2。&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/0dab2684ca6e2afc4d7f28ff6d183631.js"&gt;&lt;/script&gt;
&lt;p&gt;Python部分基本一致，只是三元運算是由if else來寫的。&lt;/p&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/53c1a4f2fa785ceaeb9fa49f44f46035.js"&gt;&lt;/script&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N)/O(N)，因為要考慮到最糟的情況，同時遞迴會產生&lt;strong&gt;call stack&lt;/strong&gt; )&lt;/p&gt;
&lt;p&gt;「能否給出迭代解？」&lt;br&gt;
(原題的&lt;a class="link" href="https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/" target="_blank" rel="noopener"
&gt;Solution&lt;/a&gt;處有給出來，請參照看看XD，簡單來說，&lt;br&gt;
就是分別使用stack記錄p跟q的祖先節點，最後回頭找最底層的那個祖先。)&lt;br&gt;
(但因為使用stack的關係，&lt;strong&gt;空間複雜度依舊會是O(N)&lt;/strong&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;</description></item><item><title>從LeetCode學演算法 - 54 DFS (2)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-54-dfs-2/</link><pubDate>Sun, 22 Sep 2019 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-54-dfs-2/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 54 DFS (2)" /&gt;&lt;p&gt;&lt;strong&gt;0114. Flatten Binary Tree to Linked List (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a binary tree, flatten it to a linked list in-place.&lt;/p&gt;
&lt;p&gt;For example, given the following tree:&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;/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 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;3 4 6
&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;The flattened tree should look like:&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;/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
&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; \
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 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; 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; 6
&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;給定一個二元樹，請將其攤平成linkedlist形式且以in-place的條件進行。&lt;br&gt;
依照題目要求攤平後，整棵樹應該會變成每一個節點只會有右邊的節點。&lt;/p&gt;
&lt;p&gt;仔細觀察題目我們會發現其走訪的順序其實是pre-order。(中左右)&lt;br&gt;
那麼，該怎麼做到攤平呢？&lt;/p&gt;
&lt;p&gt;我們可以先考慮某個子樹的情況，&lt;br&gt;
根節點自己在攤平後應該還是不會動，&lt;br&gt;
&lt;strong&gt;而所有左子樹的節點在攤平後應該都排在右子樹節點的前面&lt;/strong&gt; 。&lt;br&gt;
所以當我們假定先完成了一個樹的左右子樹的攤平的話，&lt;br&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;　 a
&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;b e
&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; c f
&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; d g
&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;將d跟e接起來(a-e斷開)&lt;/strong&gt; ，&lt;br&gt;
並且&lt;strong&gt;將b的位置從a的左邊挪到右邊&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;所以整個流程會像這樣：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;檢查&lt;strong&gt;根節點&lt;/strong&gt; ，是NIL則回傳(代表這條路走到底了)。&lt;/li&gt;
&lt;li&gt;先記錄左右節點備用(l, r)，&lt;br&gt;
並分別&lt;strong&gt;呼叫自己的左右節點進入flatten遞迴&lt;/strong&gt; 。&lt;/li&gt;
&lt;li&gt;經過2以後左右子樹應該分別攤平了，&lt;br&gt;
現在將&lt;strong&gt;左節點設為null，右節點設為l&lt;/strong&gt; 。&lt;/li&gt;
&lt;li&gt;使用迴圈找到&lt;strong&gt;root.right的最右邊的節點&lt;/strong&gt; (也就是原先左子樹的最後一個節點)，&lt;br&gt;
將其和r接起來。(也就是在做上圖的&lt;strong&gt;d跟e&lt;/strong&gt; 的銜接)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/f023fc0414c82c9e7c50441a34211153.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/004b0b352fc9107669019a4fbceac3c2.js"&gt;&lt;/script&gt;
&lt;p&gt;讀者可能會注意到上面也提供了迭代解，&lt;br&gt;
這個版本的解法源自於&lt;strong&gt;Morris Traversal&lt;/strong&gt; ，&lt;br&gt;
有興趣的讀者可以了解一下。&lt;/p&gt;
&lt;p&gt;簡單來說呢，它做的事情跟遞迴是一致的，&lt;br&gt;
不過它不需要使用到call stack，&lt;br&gt;
只需要用到&lt;strong&gt;輔助的TreeNode&lt;/strong&gt; 來記錄先前的root.right。&lt;br&gt;
每次我們會&lt;strong&gt;檢查左節點是否為NIL&lt;/strong&gt; ，&lt;br&gt;
是的話我們可以&lt;strong&gt;直接往右邊走&lt;/strong&gt; (因為左邊不用處理了)；&lt;br&gt;
接著做的事情相同，先用&lt;strong&gt;tmp暫時存下右子樹&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;其時間複雜度一樣是O(N)&lt;/strong&gt; 即可，&lt;br&gt;
在實際面對類似題目時，如果沒有把握，可以以前面的遞迴解為主。&lt;/p&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(O(N)/O(1)，但遞迴解的空間複雜度要另行考慮call stack，&lt;br&gt;
若平衡的話是O(logN))&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學演算法 - 45 DFS (1)</title><link>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-45-dfs-1/</link><pubDate>Wed, 04 Sep 2019 00:00:00 +0800</pubDate><guid>https://desolve.pages.dev/post/learn-algorithm-from-leetcode-45-dfs-1/</guid><description>&lt;img src="https://desolve.pages.dev/img/default-leetcode.webp" alt="Featured image of post 從LeetCode學演算法 - 45 DFS (1)" /&gt;&lt;p&gt;&lt;strong&gt;0200 Number of Islands (Medium)&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="question"&gt;Question
&lt;/h2&gt;&lt;p&gt;Given a 2d grid map of &lt;code&gt;'1'&lt;/code&gt;s (land) and &lt;code&gt;'0'&lt;/code&gt;s (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.&lt;/p&gt;
&lt;h3 id="example-1"&gt;Example 1
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;div style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;
&lt;table style="border-spacing:0;padding:0;margin:0;border:0;"&gt;&lt;tr&gt;&lt;td style="vertical-align:top;padding:0;margin:0;border:0;"&gt;
&lt;pre tabindex="0" style="color:#cad3f5;background-color:#24273a;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;1
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;2
&lt;/span&gt;&lt;span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#8087a2"&gt;3
&lt;/span&gt;&lt;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;Input:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;11110
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;11010
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;11000
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;00000
&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: 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;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;Input:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;11000
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;11000
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;00100
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;00011
&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: 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;strong&gt;陸地用'1&amp;rsquo;表示，水則用'0&amp;rsquo;表示&lt;/strong&gt; ，&lt;br&gt;
試計數這整張圖有多少島嶼(island)。可假定地圖的外圍均為水域。&lt;br&gt;
(島嶼的定義就是其周圍都圍繞著水，&lt;br&gt;
且可以通過連接相鄰的垂直/水平陸地所構成。)&lt;/p&gt;
&lt;p&gt;如對於題目描述依舊沒搞懂的話，就把它當成小畫家填色的色塊吧！&lt;br&gt;
視為相同區域的用油漆桶可以全部填滿XD&lt;br&gt;
而題目所問的，就相當於&lt;strong&gt;要填幾次才能將所有陸地區域填滿&lt;/strong&gt; 。&lt;/p&gt;
&lt;p&gt;對於要確認島嶼這點，只有一種方法：&lt;br&gt;
每次從一個點開始向外延伸相鄰的格子，&lt;br&gt;
直到周圍沒有可以延伸的區域為止。&lt;br&gt;
這時候這整塊區域就是我們所謂的島嶼，於是&lt;strong&gt;計數可以加1&lt;/strong&gt; 。&lt;br&gt;
那麼問題來了，在延伸的過程中一共有&lt;strong&gt;四個方向&lt;/strong&gt; 可以選擇，&lt;br&gt;
如果不加限制的話，無疑會有重複的部分；&lt;br&gt;
所以除了&lt;strong&gt;檢查是否遇到水(‘0’，也就是可以不用繼續往下搜尋)外&lt;/strong&gt; ，&lt;br&gt;
我們還需要知道這個格子是否已經走過了。&lt;br&gt;
所以我們會再&lt;strong&gt;新增一個visited陣列用來標明已經走過的區域&lt;/strong&gt; 。&lt;br&gt;
(這樣子只要已經走過的就直接跳過即可。)&lt;/p&gt;
&lt;p&gt;由於每次會需要走到底才會回頭，&lt;br&gt;
所以這種方式是很典型的&lt;strong&gt;DFS(Depth-First Search，深度優先搜尋)&lt;/strong&gt; 方法。&lt;/p&gt;
&lt;p&gt;所以流程會變成：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;初始化一個&lt;strong&gt;visited&lt;/strong&gt; 二維陣列，預設當中每個值均為&lt;strong&gt;false&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;對grid中的每個點(i, j)檢查其是否為陸地(‘1’)&lt;/strong&gt; ，且未曾走訪過的話:&lt;br&gt;
2-a. 遞增島嶼計數值，並&lt;strong&gt;從每個點(i, j)呼叫函式dfs&lt;/strong&gt; 來開始走訪&lt;/li&gt;
&lt;li&gt;在dfs中，先檢查(i, j)點是否符合規範(因會+1或-1，&lt;strong&gt;須不超出範圍&lt;/strong&gt; )，&lt;br&gt;
且&lt;strong&gt;尚未走訪過(visited[i][j] == false)&lt;/strong&gt; 的狀況，進行3-a的流程&lt;br&gt;
3-a. 將&lt;strong&gt;visited[i][j]設定為true&lt;/strong&gt;&lt;br&gt;
3-b. 往(i, j)的&lt;strong&gt;上下左右&lt;/strong&gt; 走，並傳入下一階段的dfs。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;這麼一來，當整張圖掃過去以後，&lt;br&gt;
我們就能知道到底有幾個島嶼了！&lt;/p&gt;
&lt;p&gt;Java和Python的寫法基本一致，這邊不再贅述，&lt;br&gt;
讀者只要注意到應該被檢查的&lt;strong&gt;邊界條件&lt;/strong&gt; 即可。&lt;/p&gt;
&lt;h3 id="java"&gt;Java
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/f041abe3a9e417167c1da9dc352cafa3.js"&gt;&lt;/script&gt;
&lt;h3 id="python"&gt;Python
&lt;/h3&gt;&lt;script src="https://gist.github.com/Desolve/0c36e727c43bb33f4fa4a35bb83816fd.js"&gt;&lt;/script&gt;
&lt;p&gt;在這個範例中我們使用了一個額外的陣列來儲存，&lt;br&gt;
有沒有辦法能夠不用額外的陣列呢？&lt;br&gt;
其實是有的，&lt;strong&gt;辦法就是將每次走過的陸地(‘1’)，&lt;br&gt;
都直接設定成水(‘0’)，自然就相當於都走過了&lt;/strong&gt;，&lt;br&gt;
從而可以替代掉用visited來處理。&lt;br&gt;
優點是速度會較為快速，&lt;br&gt;
但很嚴重的缺點是這麼做完以後，&lt;br&gt;
&lt;strong&gt;grid本身就會變成全部都是’0&amp;rsquo;的陣列了&lt;/strong&gt; 。&lt;br&gt;
除非已經確定這個grid可以被任意操作，&lt;br&gt;
否則筆者認為要這麼做的話記得要先問清楚要求才下手才行XD~&lt;/p&gt;
&lt;p&gt;此外，這題在返回時仍舊要&lt;strong&gt;保留走過哪些格子的資訊&lt;/strong&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-42-backtracking-1-tree-8-2f230ef087cd?source=friends_link&amp;amp;sk=55c3770b3626f512e1d1a2477f91e3a0" target="_blank" rel="noopener"
&gt;Backtracking的題目&lt;/a&gt;作法是不一樣的。&lt;/p&gt;
&lt;h2 id="面試實際可能會遇到的問題"&gt;面試實際可能會遇到的問題
&lt;/h2&gt;&lt;p&gt;「時間/空間複雜度？」&lt;br&gt;
(若m, n為長寬，O(m*n) for best case，理論上全部走訪一遍即可, O(m*n))&lt;br&gt;
(如果可以清空grid則記錄用的空間複雜度是O(1))&lt;br&gt;
(若考慮call stack的部份的話，總空間複雜度worst case是&lt;strong&gt;O(N)&lt;/strong&gt; )&lt;/p&gt;
&lt;h2 id="相似及延伸"&gt;相似及延伸
&lt;/h2&gt;&lt;p&gt;1.&lt;a class="link" href="https://leetcode.com/problems/surrounded-regions/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;0130. Surrounded Regions&lt;/strong&gt; &lt;/a&gt;2.&lt;a class="link" href="https://leetcode.com/problems/max-area-of-island/" target="_blank" rel="noopener"
&gt;&lt;strong&gt;0695. Max Area of Island&lt;/strong&gt; &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Special Thanks suggestions/corrections from viewers:&lt;br&gt;
Raiy Kuo&lt;/strong&gt;: DFS時recusive占用的stack應一併考慮進去。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;(歡迎提供意見協助更正歐~)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;從LeetCode學演算法，我們下次見囉，掰~&lt;/p&gt;</description></item></channel></rss>