{"id":1497,"date":"2019-04-11T03:30:50","date_gmt":"2019-04-11T03:30:50","guid":{"rendered":"http:\/\/www.afternerd.com\/blog\/?p=1497"},"modified":"2019-08-23T04:05:25","modified_gmt":"2019-08-23T04:05:25","slug":"flatten-binary-tree-linked-list","status":"publish","type":"post","link":"https:\/\/www.afternerd.com\/blog\/flatten-binary-tree-linked-list\/","title":{"rendered":"Python: Flatten Binary Tree to Linked List"},"content":{"rendered":"<p>In this article, I will solve a common <a href=\"https:\/\/en.wikipedia.org\/wiki\/Tree_(data_structure)\" target=\"_blank\" rel=\"noopener noreferrer\">Tree<\/a> data-structure question. This question also appears frequently in <a href=\"https:\/\/www.afternerd.com\/blog\/coding-interview\/\">coding interviews<\/a>.<\/p>\n<p>In solving this question, I will also teach you the thought process that I go through when I encounter problems like this one so you can solve similar problems on your own if you encounter them.<\/p>\n<p>I am also going to provide you with an in-depth explanation of the code, how it works, and what its time complexity is.<\/p>\n<h2>The Question<\/h2>\n<p><em>The question goes as follows:<\/em><\/p>\n<p>Given a binary tree, flatten the tree into a linked list in place.<\/p>\n<p>For example, if this is the input tree<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1499 size-large\" src=\"http:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.40.25-PM-1024x624.png\" alt=\"\" width=\"1024\" height=\"624\" srcset=\"https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.40.25-PM-1024x624.png 1024w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.40.25-PM-300x183.png 300w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.40.25-PM-768x468.png 768w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.40.25-PM-200x122.png 200w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.40.25-PM-400x244.png 400w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.40.25-PM-600x366.png 600w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.40.25-PM-800x488.png 800w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.40.25-PM-1200x731.png 1200w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.40.25-PM.png 1234w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>The output linked list should look like this<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-1501 aligncenter\" src=\"http:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.43.23-PM-300x281.png\" alt=\"\" width=\"468\" height=\"438\" srcset=\"https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.43.23-PM-300x281.png 300w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.43.23-PM-768x719.png 768w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.43.23-PM-200x187.png 200w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.43.23-PM-400x375.png 400w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.43.23-PM-600x562.png 600w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.43.23-PM-800x749.png 800w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.43.23-PM.png 976w\" sizes=\"(max-width: 468px) 100vw, 468px\" \/><\/p>\n<p>And since we are making this conversion in place, you can assume that the Tree&#8217;s <strong>right<\/strong> pointer is equivalent to a Linked List&#8217;s <strong>next<\/strong> pointer.<\/p>\n<h2>The Thought Process<\/h2>\n<p>As with all tree data structure questions, the first thing that comes to my mind when I am faced with a tree data-structure problem is to think if there is a way to solve the problem recursively through a <strong>divide and conquer<\/strong> algorithm.<\/p>\n<p>In other words,\u00a0 can I construct a solution to the main problem given the solutions of subproblems?<\/p>\n<div class=\"after-post-box\"><strong>Pro tip:<\/strong> In most tree data-structure questions, this is actually true.<\/div>\n<p>Alright, let&#8217;s go back to our problem and try to examine it again from this angle.<\/p>\n<p>By looking at the example shown, it is very obvious that the head of the output linked list is the <strong>root<\/strong> of the tree node, followed by a <strong>flattened left subtree<\/strong>, which is followed by a <strong>flattened right subtree<\/strong>.<\/p>\n<p>This simple description above is our solution.<\/p>\n<p>How you ask?<\/p>\n<p>Well, flattening the left subtree and the right subtree are the sub-problems that I talked about earlier which we can just delegate to the magic of recursion.<\/p>\n<p>Now the question is, given the solutions of these subproblems, how can we construct a solution to the main tree.<\/p>\n<p>Let&#8217;s first see how the tree will look like after we flatten the left and right subtrees.<\/p>\n<p>If we recursively flatten the left subtree and the right subtree, we will not precisely end up with the output linked list that we are looking for.<\/p>\n<p>Instead, we will end up with a tree that looks like this.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1503\" src=\"http:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.52.58-PM.png\" alt=\"\" width=\"1460\" height=\"1060\" srcset=\"https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.52.58-PM.png 1460w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.52.58-PM-300x218.png 300w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.52.58-PM-768x558.png 768w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.52.58-PM-1024x743.png 1024w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.52.58-PM-200x145.png 200w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.52.58-PM-400x290.png 400w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.52.58-PM-600x436.png 600w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.52.58-PM-800x581.png 800w, https:\/\/www.afternerd.com\/blog\/wp-content\/uploads\/2019\/04\/Screen-Shot-2019-04-08-at-8.52.58-PM-1200x871.png 1200w\" sizes=\"(max-width: 1460px) 100vw, 1460px\" \/><\/p>\n<p>This means we still need to do some more work to construct the final output, but we are in a much better state now.<\/p>\n<p><em>So how can we do that?<\/em><\/p>\n<p>It&#8217;s actually very simple.<\/p>\n<p><strong>Step 1:<\/strong> The right pointer of root should point to the head of the flattened left subtree<\/p>\n<p><strong>Step 2:<\/strong> The right pointer of the tail of the left subtree should point to the head of the right subtree<\/p>\n<p><strong>Step 3:<\/strong> The left pointer of root should point to <strong>None<\/strong><\/p>\n<h2>The Code<\/h2>\n<p>Now after this thought process that we went through, translating the solution that we came up with into code is very straight-forward.<\/p>\n<p>That&#8217;s why I encourage you, whether you are in a coding interview or not, to spend some time thinking about your solution and improving it before you dive into writing code.<\/p>\n<p>Because most of the time, writing the code is the easiest part.<\/p>\n<p>Now let&#8217;s start coding our solution up<\/p>\n<pre class=\"prettyprint linenums\"><code>def flatten(root):\r\n   if root is not None:\r\n     flatten(root.left)\r\n     flatten(root.right)\r\n     if root.left is not None:\r\n       current = root.left\r\n       while current.right is not None:\r\n         current = current.right\r\n\r\n       current.right = root.right\r\n       root.right = root.left\r\n       root.left = None<\/code><\/pre>\n<h2>Explaining the Code<\/h2>\n<p>Since this is a recursive solution, you have to think of the base case(s).<\/p>\n<p>Otherwise your code will run infinitely and neither your processor or your memory will be happy :).<\/p>\n<p>Personally, when I am solving a problem in a recursive manner, I tend to think about the recursive part of the solution first before I start thinking about the base cases.<\/p>\n<p>But it&#8217;s up to you to figure out which way you&#8217;re more comfortable with.<\/p>\n<h3>So what do you think the base case is for this problem?<\/h3>\n<p>To answer this, let&#8217;s first remember that our function doesn&#8217;t actually return anything. Everything happens in place.<\/p>\n<p>Since we are recursively flattening the left and right subtrees for each node, the questions is when do we stop?<\/p>\n<p>We can stop when we encounter a <strong>None tree node.<\/strong><\/p>\n<p>When we encounter a <strong>None tree node<\/strong>, we call it a day and we stop recursing any further.<\/p>\n<p>So the base case is:<\/p>\n<pre class=\"prettyprint\"><code>if root is None: return<\/code><\/pre>\n<p>But instead of saying that, we can also also embed all your logic in the opposite if statement<\/p>\n<pre class=\"prettyprint\"><code>if root is not None: # your logic here<\/code><\/pre>\n<p>And this is what we have in <strong>line number 2<\/strong><\/p>\n<p><strong>Line number 3<\/strong> and <strong>line number 4<\/strong> are the magical recursive function calls that solve the subproblems for the left and right subtrees.<\/p>\n<pre class=\"prettyprint\"><code>flatten(root.left)\r\nflatten(root.right)<\/code><\/pre>\n<p>Starting from <strong>line number 5<\/strong>, what we are essentially doing is constructing the solution of the main problem from the solutions of subproblems.<\/p>\n<p>But first I want you notice something.<\/p>\n<p><strong>What do you think should happen if our tree doesn&#8217;t have a left subtree?<\/strong><\/p>\n<p>Think about it.<\/p>\n<p>As a matter of fact, if there is no left subtree then we don&#8217;t need to do any extra work since the right subtree is already flattened, the root&#8217;s left pointer is pointing to None, and the root&#8217;s right pointer is pointing to the head of the right subtree.<\/p>\n<p>Sweet! we are done.<\/p>\n<p>It&#8217;s only if the left subtree exists that we need to do some extra work.<\/p>\n<p>Specifically, we need to do 3 things:<\/p>\n<h3>1. Find the tail of the flattened left subtree<\/h3>\n<p>Since the left subtree is already flattened, you can use a simple loop to reach the tail<\/p>\n<pre class=\"prettyprint\"><code>current = root.left\r\nwhile current.right is not None:\r\n  current = current.right<\/code><\/pre>\n<p>After the loop terminates, <strong>current<\/strong> will be pointing to the tail of the left subtree.<\/p>\n<h3>2. Connect the tail of the left subtree with the head of the flattened right subtree<\/h3>\n<p>Now that we identified the tail of the left subtree, we need to modify the tail&#8217;s right(next) pointer to point to the head of the flattened right subtree.<\/p>\n<p>This is what this pice of code does.<\/p>\n<pre class=\"prettyprint\"><code>current.right = root.right<\/code><\/pre>\n<h3>\u00a03. Modify the root&#8217;s left and right pointers<\/h3>\n<p>Finally, we need to modify the root&#8217;s right pointer to point to the flattened left subtree and left one to point to <strong>None<\/strong>.<\/p>\n<pre class=\"prettyprint\"><code>root.right = root.left\r\nroot.left = None<\/code><\/pre>\n<h2>Time Complexity<\/h2>\n<p>We can use <a href=\"https:\/\/en.wikipedia.org\/wiki\/Master_theorem_(analysis_of_algorithms)\" target=\"_blank\" rel=\"noopener noreferrer\">Master theorem<\/a> to find out the time complexity for our algorithm.<\/p>\n<p>If you are not familiar with Master theorem, I highly recommend that you take a look and familiarize yourself with it.<\/p>\n<p>Sometimes, using Master theorem is the simplest way to analyze the time complexity of a recursive algorithm.<\/p>\n<p>Now let&#8217;s see how we can analyze our recursive algorithm.<\/p>\n<p>Basically, to solve this problem for a tree of size n, we need to solve two subproblems for the left and right subtrees.<\/p>\n<p>In the average case, let&#8217;s assume that each subtree will be of size (n\/2).<\/p>\n<p>After the two subproblems have been resolved, constructing the solution of the original problem requires finding the tail of the left subtree which is O(log n).<\/p>\n<p>With this information, we can write the recursive formula as:<\/p>\n<p><span class=\"symbol\">T(n) = 2 * T(n \/ 2) + o(log n)<\/span><\/p>\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Master_theorem_(analysis_of_algorithms)#Application_to_common_algorithms\" target=\"_blank\" rel=\"noopener noreferrer\">By applying the Master theorem to this formula<\/a>, we get that the run time is O(n).<\/p>\n<div class=\"after-post-box\">\n<h2>Struggling with Tree data structure questions?<\/h2>\n<h3>Master Tree coding interview questions with my e-book<\/h3>\n<p>Here is what you will get in the e-book:<\/p>\n<ul>\n<li>14 problems that cover the majority of ideas for Tree coding interview questions<\/li>\n<li>In-depth explanation to each solution (like this article)<\/li>\n<li>The thought process that will help you arrive at the right solution<\/li>\n<li>How to approach solving any tree coding interview question even if you haven&#8217;t seen the question before<\/li>\n<\/ul>\n<h3>Get the E-book now for only $4.99!<\/h3>\n<form action=\"https:\/\/www.afternerd.com\/blog\/tree-mastery-ebook\/\"><button class=\"fusion-button fusion-button-default fusion-button-default-size\" style=\"width: 100%;\" type=\"submit\">I WANT TO GET THE EBOOK NOW<\/button><\/form>\n<\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":1513,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1404],"tags":[13],"yst_prominent_words":[1302,1322,1321,1325,1334,1301,1332,1331,131,1308,1333,1303,132,1287,1310,1318,1319,1275,1276,1280],"_links":{"self":[{"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/posts\/1497"}],"collection":[{"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/comments?post=1497"}],"version-history":[{"count":17,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/posts\/1497\/revisions"}],"predecessor-version":[{"id":1673,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/posts\/1497\/revisions\/1673"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/media\/1513"}],"wp:attachment":[{"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/media?parent=1497"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/categories?post=1497"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/tags?post=1497"},{"taxonomy":"yst_prominent_words","embeddable":true,"href":"https:\/\/www.afternerd.com\/blog\/wp-json\/wp\/v2\/yst_prominent_words?post=1497"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}