<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ leetcode - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ leetcode - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 26 May 2026 04:43:58 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/leetcode/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ LeetCode Meditations: A Visual Handbook of Data Structures and Algorithms Concepts ]]>
                </title>
                <description>
                    <![CDATA[ It may seem like an oxymoron when the words "LeetCode" and "meditation" are used together – after all, one thing that almost everyone can agree is that LeetCode is challenging. It's called grinding LeetCode for a reason. It doesn't have anything to d... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/leetcode-dsa-concepts-handbook/</link>
                <guid isPermaLink="false">6838baed0c839b0170a2e731</guid>
                
                    <category>
                        <![CDATA[ Computer Science ]]>
                    </category>
                
                    <category>
                        <![CDATA[ MathJax ]]>
                    </category>
                
                    <category>
                        <![CDATA[ leetcode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ DSA ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Eda Eren ]]>
                </dc:creator>
                <pubDate>Thu, 29 May 2025 19:52:13 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1748548297673/2ea8ee5a-e873-4401-b024-86412bf00f8a.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>It may seem like an oxymoron when the words "LeetCode" and "meditation" are used together – after all, one thing that almost everyone can agree is that <a target="_blank" href="https://leetcode.com/">LeetCode</a> is challenging. It's called <em>grinding</em> LeetCode for a reason.</p>
<p>It doesn't have anything to do with the platform, of course, but rather what it represents: tackling problems for hours on end, usually to find a solution that is even harder to understand.</p>
<p>But what is more challenging is finding a roadmap to solve those problems with very little knowledge of data structures and algorithms. This handbook is more or less based on the <a target="_blank" href="https://neetcode.io/practice?tab=blind75">Blind 75 list</a> that's included in <a target="_blank" href="http://neetcode.io">neetcode.io</a>'s practice problems. This is an amazing resource that offers an organized study roadmap for solving LeetCode problems.</p>
<p>In fact, why not take a more structured and <em>calmer</em> approach? We can treat learning about the topics on the list like taking a brief walk in nature – a sort of meditation, if you will.</p>
<p>That said, this handbook is not about specific problems. Rather it’s about understanding the concepts behind them in a casual manner. It is also language agnostic – sometimes you’ll see TypeScript, sometimes Python, and sometimes JavaScript.</p>
<p>This handbook also requires you to be patient, to relax, to take a step back and pay attention. The mid-quality GIFs used in the handbook (maybe ironically!) intend to encourage this. They are not videos, so you can wait for it to come to a moment that you didn't understand or missed instead of hastily rewinding it back or rushing to a certain point in the future.</p>
<p>Solving hundreds of LeetCode problems may be the gate to go through to get an interview at big tech companies…but learning the topics that the problems are about is not under anyone's monopoly.</p>
<p>With that said, let's start the first chapter.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-one-arrays-amp-hashing">Chapter One: Arrays &amp; Hashing</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-dynamic-arrays">Dynamic Arrays</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-hash-tables">Hash Tables</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-prefix-sums">Prefix Sums</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-two-two-pointers">Chapter Two: Two Pointers</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-palindrome-example">Palindrome example</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-squares-of-a-sorted-array-example">Squares of a sorted array example</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-three-sliding-window">Chapter Three: Sliding Window</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-fixed-window-size">Fixed window size</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-dynamic-window-size">Dynamic window size</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-four-stack">Chapter Four: Stack</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-five-binary-search">Chapter Five: Binary Search</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-six-linked-lists">Chapter Six: Linked Lists</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-singly-linked-lists">Singly linked lists</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-doubly-linked-lists">Doubly linked lists</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-circular-linked-lists">Circular linked lists</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-interlude-fast-amp-slow-pointers">Interlude: Fast &amp; Slow Pointers</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-finding-the-middle-node-of-a-linked-list">Finding the middle node of a linked list</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-seven-trees">Chapter Seven: Trees</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-binary-trees-binary-search-trees-bsts">Binary trees, binary search trees (BSTs)</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-inserting-into-a-binary-search-tree">Inserting into a binary search tree</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-recursive-solution">Recursive solution</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-iterative-solution">Iterative solution</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-deleting-from-a-binary-search-tree">Deleting from a binary search tree</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-traversals">Traversals</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-depth-first-search-dfs">Depth-First Search (DFS)</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-preorder-traversal">Preorder traversal</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-inorder-traversal">Inorder traversal</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-postorder-traversal">Postorder traversal</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-breadth-first-search-bfs">Breadth-First Search (BFS)</a></p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-eight-heap-priority-queue">Chapter Eight: Heap / Priority Queue</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-heap-properties">Heap properties</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-heaps-with-arrays">Heaps with arrays</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-insertingremoving-elements">Inserting/removing elements</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-heapsort">Heapsort</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-nine-backtracking">Chapter Nine: Backtracking</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-subsets">Subsets</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-ten-tries">Chapter Ten: Tries</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-eleven-graphs">Chapter Eleven: Graphs</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-representing-graphs">Representing graphs</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-edge-list">Edge List</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-adjacency-matrix">Adjacency Matrix</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-adjacency-list">Adjacency List</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-traversals-1">Traversals</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-breadth-first-search">Breadth-First Search</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-depth-first-search">Depth-First Search</a></p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-twelve-dynamic-programming">Chapter Twelve: Dynamic Programming</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-thirteen-intervals">Chapter Thirteen: Intervals</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-chapter-fourteen-bit-manipulation">Chapter Fourteen: Bit Manipulation</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-bitwise-operators">Bitwise operators</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-and-amp">AND (<code>&amp;</code>)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-or">OR (<code>|</code>)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-xor">XOR (<code>^</code>)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-not">NOT (<code>~</code>)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-left-shift-zero-fill-ltlt">Left shift (zero fill) (<code>&lt;&lt;</code>)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-right-shift-sign-preserving-gtgt">Right shift (sign preserving) (<code>&gt;&gt;</code>)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-right-shift-unsigned-gtgtgt">Right shift (unsigned) (<code>&gt;&gt;&gt;</code>)</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-getting-a-bit">Getting a bit</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-setting-a-bit">Setting a bit</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-resources-amp-credits">Resources &amp; Credits</a></p>
</li>
</ol>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before diving in, some familiarity with TypeScript/JavaScript and Python may be helpful, as these are the languages I use for the examples. Also, a basic understanding of Big O notation is useful as we go over time and space complexities.</p>
<p>Even though we don't go through the mathematics behind the concepts, some basic mathematical knowledge can also help. That said, it's definitely not necessary to enjoy or learn something useful from this handbook.</p>
<h2 id="heading-chapter-one-arrays-amp-hashing">Chapter One: Arrays &amp; Hashing</h2>
<p>Let's very briefly get to know our topics for this chapter: dynamic arrays, hash tables, and prefix sums.</p>
<h3 id="heading-dynamic-arrays">Dynamic Arrays</h3>
<p>Dynamic arrays are, well, dynamic. They're flexible and can change their size during execution.</p>
<p>Python's <code>list</code> type is a dynamic array. We can create an <code>items</code> list, for example:</p>
<pre><code class="lang-python">items = [<span class="hljs-number">3</span>, <span class="hljs-number">5</span>]
</code></pre>
<p>The <strong>length</strong> of <code>items</code> is 2, as you can see, but its <strong>capacity</strong> is greater than or equal to its length. In fact, capacity refers to the total size, whereas length is the actual size.</p>
<p>Since dynamic arrays are still arrays, they need a contiguous block of memory.</p>
<p>We can easily add an item to <code>items</code>:</p>
<pre><code class="lang-python">items.append(<span class="hljs-number">7</span>)
</code></pre>
<p>And add some more:</p>
<pre><code class="lang-python">items.append(<span class="hljs-number">9</span>)
items.append(<span class="hljs-number">11</span>)
items.append(<span class="hljs-number">13</span>)
</code></pre>
<p>All the while, the length and capacity of <code>items</code> keep growing dynamically.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747912308935/960ff442-e095-4781-8ab5-9b84e0ecb804.gif" alt="Animated visualization of four boxes for an &quot;items&quot; array that holds the values 3 and 5 on initialization, appending 7 to the array adds four more boxes to it." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<h4 id="heading-time-and-space-complexity">Time and space complexity</h4>
<p>Accessing an element is \(O(1)\) as we have <a target="_blank" href="https://en.wikipedia.org/wiki/Random_access">random access</a>.</p>
<p>Inserting a new element or deleting an element is \(O(n)\) (think about having to shift all the elements before inserting or after deleting an item). But, in order to not be too pessimistic, we can look at <a target="_blank" href="https://en.wikipedia.org/wiki/Amortized_analysis">amortized analysis</a> – in that case, inserting/deleting at the end of the array becomes \(O(1)\).</p>
<p>Space complexity is \(O(n)\), as the need for space will grow proportionately as the input increases.</p>
<p>If you need more info about time and space complexity, you can <a target="_blank" href="https://www.freecodecamp.org/news/big-o-notation-why-it-matters-and-why-it-doesnt-1674cfa8a23c/">refer to this guide</a>.</p>
<h3 id="heading-hash-tables">Hash Tables</h3>
<p>A hash table maps keys to values, implementing an <em>associative array</em>.</p>
<p>Python's <code>dict</code> is one example:</p>
<pre><code class="lang-python">number_of_petals = {
    <span class="hljs-string">'Euphorbia'</span>: <span class="hljs-number">2</span>, 
    <span class="hljs-string">'Trillium'</span>: <span class="hljs-number">3</span>, 
    <span class="hljs-string">'Columbine'</span>: <span class="hljs-number">5</span>,
}
</code></pre>
<p>Also JavaScript's "object"s:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> numberOfMoons = {
  <span class="hljs-string">'Earth'</span>: <span class="hljs-number">1</span>,
  <span class="hljs-string">'Mars'</span>: <span class="hljs-number">2</span>,
  <span class="hljs-string">'Jupiter'</span>: <span class="hljs-number">95</span>,
  <span class="hljs-string">'Saturn'</span>: <span class="hljs-number">146</span>,
  <span class="hljs-string">'Uranus'</span>: <span class="hljs-number">27</span>,
  <span class="hljs-string">'Neptune'</span>: <span class="hljs-number">14</span>,
};
</code></pre>
<p>There are two important ingredients for a hash table:</p>
<ul>
<li><p>an array of "buckets" to store the data</p>
</li>
<li><p>a hash function to map the data to a specific index in the array</p>
</li>
</ul>
<p>Hashes are usually large integers, so to find an index, we can take the result of the hash modulo the array's length.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747913143164/2a8371ba-133c-4d5a-a270-b44f935fc91b.gif" alt="Animated visualization of an array with 5 buckets, the hash function finding a bucket for each value in number_of_petals dict." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p><strong>Note:</strong> The <strong>hash function</strong> that's mapping the elements to buckets is <strong>not</strong> the <code>hash()</code> used in the visual (it's just a <a target="_blank" href="https://docs.python.org/3/library/functions.html#hash">Python function</a> to calculate the hash value of an object). The hash function in this case is the modulo ( <code>%</code> ) operation.</p>
<p>Here, with the hash value of each item's key, we calculate the remainder when it's divided by the length of the array to find which "bucket" it should go to.</p>
<p>The ratio of the number of elements to the number of buckets is called the <strong>load factor</strong>, and the higher it gets, the more <strong>collisions</strong> (when elements have to be inserted at the same place in the array) occur.</p>
<p>There are some collusion resolution tactics like <strong>linear probing</strong> (probing through the array until finding an empty bucket) and <strong>chaining</strong> (chaining multiple elements as linked lists), but we'll not go into those for now.</p>
<h4 id="heading-time-and-space-complexity-1">Time and space complexity</h4>
<p>The average case for searching, inserting, and deleting operations are \(O(1)\) as we use keys to look up the values.</p>
<p>Space complexity is \(O(n)\) as it grows linearly with the amount of elements.</p>
<h3 id="heading-prefix-sums">Prefix Sums</h3>
<p>A prefix sum is the sequence of numbers we get after adding the sums of running totals of another sequence. It's also called the <strong>cumulative sum</strong>.</p>
<p>The first element of the resulting array is the first element of the input array. That's fine. We start at the second item, and add the previous numbers each time as we go. That is:</p>
<p>$$result[i] = \begin{cases} nums[0] &amp; \text{if } i \text{ is zero} \\ result[i - 1] + nums[i] &amp; \text{if } i \geq 1 \end{cases}$$</p><p>In code, we can implement that easily:</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">runningSum</span>(<span class="hljs-params">nums</span>):</span>
    result = [nums[<span class="hljs-number">0</span>]]

    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">1</span>, len(nums)):
        result.append(result[i - <span class="hljs-number">1</span>] + nums[i])

    <span class="hljs-keyword">return</span> result
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747913501237/e9c95eef-6310-457c-b94e-da5a61fc890a.gif" alt="Animated visualization of runningSum of the array [1, 2, 3, 4, 5]." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<h4 id="heading-time-and-space-complexity-2">Time and space complexity</h4>
<p>Time complexity for a prefix sum is \(O(n)\) because we're iterating over each of the elements in the array.</p>
<p>The space complexity is also \(O(n)\) because the need for external space grows as the length of the original array grows.</p>
<h2 id="heading-chapter-two-two-pointers">Chapter Two: Two Pointers</h2>
<p>One of the techniques of iterating through an array is the <strong>two pointers technique</strong>, and it is as simple as it sounds: we just keep two pointers, one starting from the left, and the other from the right, gradually getting closer to each other.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747913831967/b8e251a9-2e9e-41be-84ed-46f2559b1515.gif" alt="Animated visualization of two pointers technique" class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<h3 id="heading-palindrome-example">Palindrome example</h3>
<p>A very basic example can be the one where we check if a string is a palindrome or not. A palindrome is a string that reads the same forwards and backwards.</p>
<p>In an imaginary world where all the inputs always consist of lowercase English letters, we can do it like this:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// s consists of lowercase English letters</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isPalindrome</span>(<span class="hljs-params">s: <span class="hljs-built_in">string</span></span>) </span>{
  <span class="hljs-keyword">let</span> left = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">let</span> right = s.length - <span class="hljs-number">1</span>;

  <span class="hljs-keyword">while</span> (left &lt;= right) {
    <span class="hljs-keyword">if</span> (s[left++] !== s[right--]) {
      <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }
  }

  <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
}
</code></pre>
<p>We initialize two pointers: <code>left</code> and <code>right</code>. <code>left</code> points to the start of the array, while the <code>right</code> points to the last element. As we loop while <code>left</code> is less than <code>right</code>, we check if they are equal. If not, we return <code>false</code> immediately. Otherwise, our <code>left</code> pointer is increased – that is, it's moved to the <em>right</em> one step, and our <code>right</code> pointer is decreased, meaning that it's moved to the <em>left</em> one step. When they eventually overlap, the loop terminates, and we return <code>true</code>.</p>
<p>Let's say our string is <code>'racecar'</code>, which is a palindrome. It will go like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747913932303/e60727a0-4e45-4452-8648-d35d1ae680c9.gif" alt="Animated visualization of isPalindrome, with the example 'racecar' resulting in true." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<h3 id="heading-squares-of-a-sorted-array-example">Squares of a sorted array example</h3>
<p>Another example where we can use the two pointers technique is the problem <a target="_blank" href="https://leetcode.com/problems/squares-of-a-sorted-array">Squares of a Sorted Array</a>.</p>
<p>The description says:</p>
<blockquote>
<p>Given an integer array <code>nums</code> sorted in <strong>non-decreasing</strong> order, return <em>an array of</em> <strong><em>the squares of each number</em></strong> <em>sorted in non-decreasing order</em>.</p>
</blockquote>
<p>For example, if the input is <code>[-4, -1, 0, 3, 10]</code>, the output should be <code>[0, 1, 9, 16, 100]</code>.</p>
<p>Now obviously, we can just square each one, and then sort the array with a built-in sort method, and be done with it. But a sorting operation is never better than \(O(n \ log \ n)\) runtime, so we can do it using two pointers in just \(O(n)\) time:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sortedSquares</span>(<span class="hljs-params">nums: <span class="hljs-built_in">number</span>[]</span>): <span class="hljs-title">number</span>[] </span>{
  <span class="hljs-keyword">let</span> left = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">let</span> right = nums.length - <span class="hljs-number">1</span>;
  <span class="hljs-keyword">let</span> result = [];

  <span class="hljs-keyword">while</span> (left &lt;= right) {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Math</span>.abs(nums[left]) &gt; <span class="hljs-built_in">Math</span>.abs(nums[right])) {
      result.push(nums[left++] ** <span class="hljs-number">2</span>);
    } <span class="hljs-keyword">else</span> {
      result.push(nums[right--] ** <span class="hljs-number">2</span>);
    }
  }

  <span class="hljs-keyword">return</span> result.reverse();
}
</code></pre>
<p>We compare the absolute value of the items that <code>left</code> and <code>right</code> are pointing to, and push the square of the greater one to our <code>result</code> array. And we return the reversed version of it.</p>
<p><strong>Note:</strong> The reason we return the reversed result is that the array is initially already sorted, and we get the largest absolute value first. The reason that works is related to how <em>two pointers</em> work: as we start from both ends, we initially start with the smallest and largest values in the array.</p>
<p>Because we only make one pass through the array while comparing, and then later reversing, it ends up being \(O(n)\), a better runtime than \(O(n \ log \ n)\).</p>
<h2 id="heading-chapter-three-sliding-window">Chapter Three: Sliding Window</h2>
<p>Now that we're familiar with the Two Pointers technique, we can add another one to our toolbox: the Sliding Window. It's usually used for operations done on the subsets of a given data. It also comes in two flavors: <strong>fixed window size</strong> and <strong>dynamic window size</strong>.</p>
<h3 id="heading-fixed-window-size">Fixed window size</h3>
<p>If we have a size constraint in a given problem – say, we need to check a \(k\)-sized subarray – sliding window is an appropriate technique to use.</p>
<p>For example, getting the maximum subarray (of size \(k\)) sum of a given array can be done like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747914357907/ecd51e70-e649-4856-a563-47621b950526.gif" alt="Animated visualization of fixed window size sliding window technique, array [1, 5, 4, 2, 9] with k = 3, having the maxSum of 15." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>Note that the window size is \(k\), and it doesn't change throughout the operation – hence, <strong>fixed size</strong>.</p>
<p>A very cool thing to notice here is that with each <strong>slide</strong>, what happens to our sum is that we <em>add</em> the right element, and <em>decrease</em> the left element.</p>
<p>Let's look at an example for getting the maximum sum of subarray with given size <code>k</code>:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">maxSubarray</span>(<span class="hljs-params">numbers: <span class="hljs-built_in">number</span>[], k: <span class="hljs-built_in">number</span></span>) </span>{
  <span class="hljs-keyword">if</span> (numbers.length &lt; k) {
    <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;
  }

  <span class="hljs-keyword">let</span> currentSum = <span class="hljs-number">0</span>;

  <span class="hljs-comment">// Initial sum of the first window </span>
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; k; i++) {
    currentSum += numbers[i];
  }

  <span class="hljs-keyword">let</span> maxSum = currentSum;

  <span class="hljs-keyword">let</span> left = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">let</span> right = k;

  <span class="hljs-keyword">while</span> (right &lt; numbers.length) {
    currentSum = currentSum - numbers[left++] + numbers[right++];
    maxSum = <span class="hljs-built_in">Math</span>.max(maxSum, currentSum);
  }

  <span class="hljs-keyword">return</span> maxSum;
}
</code></pre>
<p><strong>Note:</strong> Updating the pointers can be done outside the brackets as well, like this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">while</span> (right &lt; numbers.length) {
  currentSum = currentSum - numbers[left] + numbers[right];
  maxSum = <span class="hljs-built_in">Math</span>.max(maxSum, currentSum);
  left++;
  right++;
}
</code></pre>
<p>Since the postfix operator returns the value first, they can be used inside the brackets to be slightly more concise.</p>
<p>Here, we first get the initial sum of our window using the <code>for</code> loop, and set it as the maximum sum.</p>
<p>Then we initialize two pointers: <code>left</code> that points to the left end of the window, and <code>right</code> that points to the right end of the window. As we loop, we update our <code>currentSum</code>, decreasing the <code>left</code> value, and adding the <code>right</code> value. When our current sum is more than the maximum sum, <code>maxSum</code> variable is updated as well.</p>
<h3 id="heading-dynamic-window-size">Dynamic window size</h3>
<p>As opposed to the fixed window size version, the size of the window changes dynamically this time.</p>
<p>For example, let's take a brief look at the problem <a target="_blank" href="https://leetcode.com/problems/best-time-to-buy-and-sell-stock">Best Time to Buy and Sell Stock</a>. We need to choose a day to buy a stock, and sell it in the <em>future</em>. The numbers in the array are prices, and we need to buy the stock at as low a price as we can, and sell it as high as we can.</p>
<p>We can initialize <code>left</code> and <code>right</code> pointers again, but this time, we'll update them depending on a condition. When the left item is less than the one on the right, that means it's good – we can buy and sell at those prices, so we get their difference and update our <code>maxDiff</code> variable that holds the maximum difference between the two.</p>
<p>If, however, the left one is greater than the right one, we update our <code>left</code> pointer to be where the <code>right</code> is at. In both cases, we'll continue updating <code>right</code> until we reach the end of the array.</p>
<p>With the blue arrow indicating the left pointer, and the red the right one, the process looks like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747914550588/222996a0-d2a6-414e-86cf-fe60deb908d8.gif" alt="Animated visualization of dynamic window size sliding window technique, array [7, 1, 5, 3, 6] having the maxDiff of 5." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>The solution looks like this:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">maxProfit</span>(<span class="hljs-params">prices: <span class="hljs-built_in">number</span>[]</span>): <span class="hljs-title">number</span> </span>{
  <span class="hljs-keyword">let</span> left = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">let</span> right = left + <span class="hljs-number">1</span>;
  <span class="hljs-keyword">let</span> maxDiff = <span class="hljs-number">0</span>;

  <span class="hljs-keyword">while</span> (right &lt; prices.length) {
    <span class="hljs-keyword">if</span> (prices[left] &lt; prices[right]) {
      <span class="hljs-keyword">let</span> diff = prices[right] - prices[left];
      maxDiff = <span class="hljs-built_in">Math</span>.max(maxDiff, diff);
    } <span class="hljs-keyword">else</span> {
      left = right;
    }

    right++;
  }

  <span class="hljs-keyword">return</span> maxDiff;
}
</code></pre>
<p><strong>Note:</strong> This one is also called <strong>fast/catch-up</strong> version of dynamic sliding window, because the <code>left</code> pointer jumps to catch up with the <code>right</code> pointer in the <code>else</code> block.</p>
<h4 id="heading-time-and-space-complexity-3">Time and space complexity</h4>
<p>Both examples have the same time and space complexity: The time complexity is \(O(n)\) because in the worst case we iterate through all the elements in the array. The space complexity is \(O(1)\) as we don't need additional space.</p>
<h2 id="heading-chapter-four-stack">Chapter Four: Stack</h2>
<p>A stack data type is perhaps one of the most well-known ones. A stack of books might be a good example to visualize, but insertion and deletion can only happen from the one end. A stack operates through the last-in first-out (LIFO) principle: the last item to go in is the first to go out.</p>
<p>Usually we'll have methods for <em>pushing</em> an element onto the stack, and <em>popping</em> an element from the stack.</p>
<p>For example, let's say we're looking for valid parentheses in a given string, and the operation we'll do goes like this.</p>
<p>As we iterate over the characters in the string, we <em>push</em> the character onto the stack. If we pushed a closing parenthesis (one of <code>)</code>, <code>}</code>, or <code>]</code>), then, if the previous pushed element is its opening pair, we'll <em>pop</em> that pair from the stack.</p>
<p>If, at the end, the stack is empty, the string consists of valid parentheses.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747914829489/e86baf72-22f6-41fe-9de9-f4da136a8777.gif" alt="Animated visualization of pushing to and popping off from a stack of parentheses." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>A stack can be implemented as an array or a linked list. But using linked lists is more common because with arrays, we have a potential <em>stack overflow</em> when we predefine a maximum stack size. On the other hand, linked lists are not static when it comes to memory, so they are a good candidate to implement stacks.</p>
<p>Linked lists are also efficient because we are using one end of the stack for insertion and deletion, and doing these are constant time operations.</p>
<p>Let's look at one easy stack implementation in Python.</p>
<p>Now, we can use a <code>list</code>, but <a target="_blank" href="https://docs.python.org/3/faq/design.html#how-are-lists-implemented-in-cpython">a list in Python is implemented as a dynamic array underneath</a>, so at one point, pushing an item can be an \(O(n)\) operation if the list needs to be copied into another memory location. For that reason, we'll use a <a target="_blank" href="https://docs.python.org/3/library/collections.html#collections.deque"><code>deque</code></a>, which is implemented as a doubly-linked list, so that we know push and pop operations will be \(O(1)\).</p>
<pre><code class="lang-python"><span class="hljs-keyword">from</span> collections <span class="hljs-keyword">import</span> deque

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stack</span>:</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">__init__</span>(<span class="hljs-params">self</span>):</span>
        self._stack = deque()

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">push</span>(<span class="hljs-params">self, item</span>):</span>
        self._stack.append(item)

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">pop</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> self._stack.pop()

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">peek</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> self._stack[<span class="hljs-number">-1</span>]

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">is_empty</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">not</span> bool(len(self._stack))

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">size</span>(<span class="hljs-params">self</span>):</span>
        <span class="hljs-keyword">return</span> len(self._stack)
</code></pre>
<p>In addition to <code>push</code> and <code>pop</code>, we'll also usually have functions like <code>peek</code> to get the topmost item in the stack, <code>is_empty</code> to check if the stack is empty, and <code>size</code> to get the size of the stack.</p>
<p>We can also do it using JavaScript. Now, we can do it using an array, but we want to use a linked list instead. Since we don't have a robust built-in library like Python this time, we'll implement a very simple version of it ourselves. Even though we haven't seen linked lists so far, the basic idea is that we have nodes, each of which has a <code>data</code> value, and a <code>next</code> pointer pointing to the next node.</p>
<p>Let's create a simple node first:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span> </span>{
  <span class="hljs-keyword">constructor</span>(data) {
    <span class="hljs-built_in">this</span>.data = data;
    <span class="hljs-built_in">this</span>.next = <span class="hljs-literal">null</span>;
  }
}
</code></pre>
<p>We can write our stack now:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Stack</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">this</span>.top = <span class="hljs-literal">null</span>;
    <span class="hljs-built_in">this</span>.length = <span class="hljs-number">0</span>;
  }

  push(item) {
    <span class="hljs-keyword">const</span> node = <span class="hljs-keyword">new</span> Node(item);
    node.next = <span class="hljs-built_in">this</span>.top;
    <span class="hljs-built_in">this</span>.top = node;
    <span class="hljs-built_in">this</span>.length++;
  }

  pop() {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.isEmpty()) { <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; }

    <span class="hljs-keyword">const</span> data = <span class="hljs-built_in">this</span>.top.data;
    <span class="hljs-built_in">this</span>.top = <span class="hljs-built_in">this</span>.top.next;
    <span class="hljs-built_in">this</span>.length--;

    <span class="hljs-keyword">return</span> data;
  }

  peek() {
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.isEmpty()) { <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; }

    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.top.data;
  }

  isEmpty() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.size() === <span class="hljs-number">0</span>;
  }

  size() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.length;
  }
}
</code></pre>
<p>Now, let’s use it:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> myStack = <span class="hljs-keyword">new</span> Stack();

myStack.push(<span class="hljs-number">5</span>);
myStack.push(<span class="hljs-number">17</span>);
myStack.push(<span class="hljs-number">55345</span>);
myStack.push(<span class="hljs-number">0</span>);
myStack.push(<span class="hljs-number">103</span>)

<span class="hljs-built_in">console</span>.log(myStack.size()) <span class="hljs-comment">// 5</span>
<span class="hljs-built_in">console</span>.log(myStack.peek()) <span class="hljs-comment">// 103</span>

myStack.pop()

<span class="hljs-built_in">console</span>.log(myStack.size()) <span class="hljs-comment">// 4</span>
<span class="hljs-built_in">console</span>.log(myStack.peek()) <span class="hljs-comment">// 0</span>
</code></pre>
<h4 id="heading-time-and-space-complexity-4">Time and space complexity</h4>
<p>Each method we defined for our stack has \(O(1)\) time complexity, and it would be the same if we were to use an array as well. However, as mentioned above, arrays have limitations in that having to allocate a predefined stack size can lead to a stack overflow. And if we were to use a dynamic array, the whole array might need to be copied to go into another memory location after a certain size is reached, leading to \(O(n)\) time. So, linked lists are ideal to implement a stack data type.</p>
<p>If the space complexity is linear – \(O(n)\)– the stack will grow linearly with the number of items in it.</p>
<h2 id="heading-chapter-five-binary-search">Chapter Five: Binary Search</h2>
<p>Binary search is one of the most well-known algorithms. It's also a <a target="_blank" href="https://brilliant.org/wiki/divide-and-conquer/">divide-and-conquer algorithm</a>, where we break the problem into smaller components.</p>
<p>The crux of binary search is to find a target element in a given sorted array. We have two pointers: <code>high</code> to point to the largest element, and <code>low</code> to point to the smallest element. We first initialize them for the whole array itself, with <code>high</code> being the last index and <code>low</code> being the first index.</p>
<p>Then, we calculate the midpoint. If the target is greater than the midpoint, then we adjust our <code>low</code> pointer to point to the <code>mid + 1</code>, otherwise if the target is less than the midpoint, we adjust <code>high</code> to be <code>mid - 1</code>. With each iteration, we eliminate half the array until the midpoint equals the target or the <code>low</code> pointer passes <code>high</code>.</p>
<p>If we find the index of the target, we can return it as soon as we find it. Otherwise, we can just return <code>-1</code> to indicate that the target doesn't exist in the array.</p>
<p>For example, if we have a <code>nums</code> array <code>[-1, 0, 3, 5, 9, 12]</code> and our <code>target</code> is <code>9</code>, the operation looks like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747915126875/c27134cb-ae7c-4f09-88d8-13fc64900319.gif" alt="Animated visualization of binary search, array [-1, 0, 3, 5, 9. 12] with target = 9, the result being the index 4." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>We can write it in TypeScript like this:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">search</span>(<span class="hljs-params">nums: <span class="hljs-built_in">number</span>[], target: <span class="hljs-built_in">number</span></span>): <span class="hljs-title">number</span> </span>{
  <span class="hljs-keyword">let</span> high = nums.length - <span class="hljs-number">1</span>;
  <span class="hljs-keyword">let</span> low = <span class="hljs-number">0</span>;

  <span class="hljs-keyword">while</span> (high &gt;= low) {
    <span class="hljs-keyword">let</span> mid = <span class="hljs-built_in">Math</span>.floor((high + low) / <span class="hljs-number">2</span>);

    <span class="hljs-keyword">if</span> (target &gt; nums[mid]) {
      low = mid + <span class="hljs-number">1</span>;
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (target &lt; nums[mid]) {
      high = mid - <span class="hljs-number">1</span>;
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">return</span> mid;
    }
  }

  <span class="hljs-keyword">return</span> <span class="hljs-number">-1</span>;
}
</code></pre>
<h4 id="heading-time-and-space-complexity-5">Time and space complexity</h4>
<p>The time complexity of a binary search algorithm is \(O(log \ n)\) in the worst case. (For example, if the target is not in the array, we'll be halving the array until there is one element left.) The space complexity is \(O(1)\) as we don't need extra space.</p>
<h2 id="heading-chapter-six-linked-lists">Chapter Six: Linked Lists</h2>
<p>A linked list is a linear data structure that you're likely to be familiar with. It is also a data structure that can grow and shrink dynamically – so unlike arrays, there's no need to allocate memory beforehand.</p>
<p>An important part of a linked list is the <strong>head pointer</strong> that points to the beginning of the list. There may or may not be a <strong>tail pointer</strong> that also points to the end of the list.</p>
<p>The core ingredient of a linked list is a simple node, which consists of two parts: data and the next pointer. So, it is an important idea to remember: <em>a node only knows about its data and its neighbor.</em></p>
<p>The very last node in the linked list points to <code>null</code> to indicate it's the end of the list.</p>
<p>But there are different types of linked lists that differ from each other slightly, so let's briefly take a look at them.</p>
<h3 id="heading-singly-linked-lists">Singly linked lists</h3>
<p>The core idea with singly linked lists is that each node, along with the data it has, has a pointer that points <em>only</em> to the next node:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span> </span>{
  <span class="hljs-keyword">constructor</span>(data) {
    <span class="hljs-built_in">this</span>.data = data;
    <span class="hljs-built_in">this</span>.next = <span class="hljs-literal">null</span>;
  }
}
</code></pre>
<p>And here is an example where we have three nodes, holding the values <code>1</code>, <code>2</code>, and <code>3</code> consecutively:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747915365474/8604a69f-f24f-4dc5-b4a0-2eba452a4305.gif" alt="Animated visualization of a singly linked list, with nodes having 1, 2, and 3 as values." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>Here is a simple implementation of a singly linked list in JavaScript:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SinglyLinkedList</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">this</span>.head = <span class="hljs-literal">null</span>;
    <span class="hljs-built_in">this</span>.tail = <span class="hljs-literal">null</span>;
    <span class="hljs-built_in">this</span>.length = <span class="hljs-number">0</span>;
  }

  <span class="hljs-comment">// Add value to the end of the list</span>
  append(value) {
    <span class="hljs-keyword">let</span> node = <span class="hljs-keyword">new</span> Node(value);
    <span class="hljs-comment">// If the list is empty</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head === <span class="hljs-literal">null</span>) {
      <span class="hljs-built_in">this</span>.head = node;
      <span class="hljs-built_in">this</span>.tail = <span class="hljs-built_in">this</span>.head;
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-built_in">this</span>.tail.next = node;
      <span class="hljs-built_in">this</span>.tail = node;
    }

    <span class="hljs-built_in">this</span>.length++;
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>;
  }

  <span class="hljs-comment">// Add value to the beginning of the list</span>
  prepend(value) {
    <span class="hljs-keyword">let</span> node = <span class="hljs-keyword">new</span> Node(value);
    <span class="hljs-comment">// If the list is empty</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head === <span class="hljs-literal">null</span>) {
      <span class="hljs-built_in">this</span>.head = node;
      <span class="hljs-built_in">this</span>.tail = <span class="hljs-built_in">this</span>.head;
    } <span class="hljs-keyword">else</span> {
      node.next = <span class="hljs-built_in">this</span>.head;
      <span class="hljs-built_in">this</span>.head = node;
    }

    <span class="hljs-built_in">this</span>.length++;
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>;
  }

  remove(value) {
    <span class="hljs-comment">// If the list is empty, return null</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head === <span class="hljs-literal">null</span>) { 
      <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; 
    }

    <span class="hljs-comment">// If it is the first element</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head.data === value) {
      <span class="hljs-built_in">this</span>.head = <span class="hljs-built_in">this</span>.head.next;
      <span class="hljs-built_in">this</span>.length--;
      <span class="hljs-comment">// If it is the only element </span>
      <span class="hljs-comment">// (we don't have anything after removing it)</span>
      <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head === <span class="hljs-literal">null</span>) {
        <span class="hljs-built_in">this</span>.tail = <span class="hljs-literal">null</span>;
      } 
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">let</span> currentNode = <span class="hljs-built_in">this</span>.head;

    <span class="hljs-keyword">while</span> (currentNode.next) {
      <span class="hljs-keyword">if</span> (currentNode.next.data === value) {
        currentNode.next = currentNode.next.next;
        <span class="hljs-comment">// If it is the last element, update tail</span>
        <span class="hljs-keyword">if</span> (currentNode.next === <span class="hljs-literal">null</span>) {
          <span class="hljs-built_in">this</span>.tail = currentNode;
        } 
        <span class="hljs-built_in">this</span>.length--;
        <span class="hljs-keyword">return</span>;
      }
      currentNode = currentNode.next;
    }
  }

  search(value) {
    <span class="hljs-keyword">let</span> currentNode = <span class="hljs-built_in">this</span>.head;

    <span class="hljs-keyword">while</span> (currentNode) {
      <span class="hljs-keyword">if</span> (currentNode.data === value) {
        <span class="hljs-keyword">return</span> currentNode;
      }
      currentNode = currentNode.next;
    }

    <span class="hljs-comment">// If the value does not exist, return null</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
  }

  printList() {
    <span class="hljs-keyword">let</span> values = [];
    <span class="hljs-keyword">let</span> currentNode = <span class="hljs-built_in">this</span>.head;
    <span class="hljs-keyword">while</span> (currentNode) {
      values.push(currentNode.data);
      currentNode = currentNode.next;
    }

    <span class="hljs-built_in">console</span>.log(values);
  }
}
</code></pre>
<p><strong>Note:</strong> We'll keep a tail pointer in all these examples for convenience. It <a target="_blank" href="https://softwareengineering.stackexchange.com/a/301863">doesn't hurt</a> to have a tail pointer.</p>
<p>We can now use it:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> mySinglyLinkedList = <span class="hljs-keyword">new</span> SinglyLinkedList();

mySinglyLinkedList.prepend(<span class="hljs-number">3</span>);
mySinglyLinkedList.prepend(<span class="hljs-number">143</span>);
mySinglyLinkedList.prepend(<span class="hljs-number">5</span>);

mySinglyLinkedList.printList(); <span class="hljs-comment">// [ 5, 143, 3 ]</span>

mySinglyLinkedList.append(<span class="hljs-number">21</span>);
mySinglyLinkedList.printList(); <span class="hljs-comment">// [ 5, 143, 3, 21 ]</span>

<span class="hljs-built_in">console</span>.log(mySinglyLinkedList.search(<span class="hljs-number">143</span>));
<span class="hljs-comment">// Node {</span>
<span class="hljs-comment">//   data: 143,</span>
<span class="hljs-comment">//   next: Node { data: 3, next: Node { data: 21, next: null } }</span>
<span class="hljs-comment">// }</span>

mySinglyLinkedList.remove(<span class="hljs-number">143</span>);
mySinglyLinkedList.printList(); <span class="hljs-comment">// [ 5, 3, 21 ]</span>

<span class="hljs-built_in">console</span>.log(mySinglyLinkedList.search(<span class="hljs-number">143</span>)); <span class="hljs-comment">// null</span>
</code></pre>
<h3 id="heading-doubly-linked-lists">Doubly linked lists</h3>
<p>Doubly linked lists differ from the "singly" ones in that each node also has another pointer that points to the previous element.</p>
<p>So, this time, a single node will look different:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span> </span>{
  <span class="hljs-keyword">constructor</span>(data) {
    <span class="hljs-built_in">this</span>.data = data;
    <span class="hljs-built_in">this</span>.next = <span class="hljs-literal">null</span>;
    <span class="hljs-built_in">this</span>.previous = <span class="hljs-literal">null</span>;
  }
}
</code></pre>
<p>Here is the same example as above, but as a doubly linked list:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747915463580/605d3541-a702-4bef-9777-28c47800b7aa.gif" alt="Animated visualization of a doubly linked list, with nodes having 1, 2 and 3 as values." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>A simple implementation might look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">DoublyLinkedList</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">this</span>.head = <span class="hljs-literal">null</span>;
    <span class="hljs-built_in">this</span>.tail = <span class="hljs-literal">null</span>;
    <span class="hljs-built_in">this</span>.length = <span class="hljs-number">0</span>;
  }

  <span class="hljs-comment">// Add value to the end of the list</span>
  append(value) {
    <span class="hljs-keyword">let</span> node = <span class="hljs-keyword">new</span> Node(value);
    <span class="hljs-comment">// If the list is empty</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head === <span class="hljs-literal">null</span>) {
      <span class="hljs-built_in">this</span>.head = node;
      <span class="hljs-built_in">this</span>.tail = <span class="hljs-built_in">this</span>.head;
    } <span class="hljs-keyword">else</span> {
      node.previous = <span class="hljs-built_in">this</span>.tail;
      <span class="hljs-built_in">this</span>.tail.next = node;
      <span class="hljs-built_in">this</span>.tail = node;
    }

    <span class="hljs-built_in">this</span>.length++;
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>;
  }

  <span class="hljs-comment">// Add value to the beginning of the list</span>
  prepend(value) {
    <span class="hljs-keyword">let</span> node = <span class="hljs-keyword">new</span> Node(value);
    <span class="hljs-comment">// If the list is empty</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head === <span class="hljs-literal">null</span>) {
      <span class="hljs-built_in">this</span>.head = node;
      <span class="hljs-built_in">this</span>.tail = <span class="hljs-built_in">this</span>.head;
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-built_in">this</span>.head.previous = node;
      node.next = <span class="hljs-built_in">this</span>.head;
      <span class="hljs-built_in">this</span>.head = node;
    }

    <span class="hljs-built_in">this</span>.length++;
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>;
  }

  remove(value) {
    <span class="hljs-comment">// If the list is empty, return null</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head === <span class="hljs-literal">null</span>) { 
      <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
    }

    <span class="hljs-keyword">let</span> currentNode = <span class="hljs-built_in">this</span>.head;

    <span class="hljs-comment">// If it is the first element</span>
    <span class="hljs-keyword">if</span> (currentNode.data === value) {
      <span class="hljs-built_in">this</span>.head = currentNode.next;
      <span class="hljs-comment">// If the removed element is not the only one,</span>
      <span class="hljs-comment">// make the previous pointer of the new head null</span>
      <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head) {
        <span class="hljs-built_in">this</span>.head.previous = <span class="hljs-literal">null</span>;
      <span class="hljs-comment">// If the removed element was the only element,</span>
      <span class="hljs-comment">// point the tail to null as well</span>
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-built_in">this</span>.tail = <span class="hljs-literal">null</span>;
      }
      <span class="hljs-built_in">this</span>.length--;
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">while</span> (currentNode) {
      <span class="hljs-keyword">if</span> (currentNode.data === value) {
        <span class="hljs-keyword">if</span> (currentNode.previous) {
          currentNode.previous.next = currentNode.next;
        }
        <span class="hljs-keyword">if</span> (currentNode.next) {
          currentNode.next.previous = currentNode.previous;
        <span class="hljs-comment">// If it's the last element in the list, update tail</span>
        <span class="hljs-comment">// to point to the previous node</span>
        } <span class="hljs-keyword">else</span> {
          <span class="hljs-built_in">this</span>.tail = currentNode.previous;
        }

        <span class="hljs-built_in">this</span>.length--;
        <span class="hljs-keyword">return</span>;
      }

      currentNode = currentNode.next;
    }
  }

  search(value) {
    <span class="hljs-keyword">let</span> currentNode = <span class="hljs-built_in">this</span>.head;
    <span class="hljs-keyword">while</span> (currentNode) {
      <span class="hljs-keyword">if</span> (currentNode.data === value) {
        <span class="hljs-keyword">return</span> currentNode;
      }
      currentNode = currentNode.next;
    }

    <span class="hljs-comment">// If the value does not exist, return null</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
  }

  printList() {
    <span class="hljs-keyword">let</span> values = [];
    <span class="hljs-keyword">let</span> currentNode = <span class="hljs-built_in">this</span>.head;

    <span class="hljs-keyword">while</span> (currentNode) {
      values.push(currentNode.data);
      currentNode = currentNode.next;
    }

    <span class="hljs-built_in">console</span>.log(values);
  }
}
</code></pre>
<h3 id="heading-circular-linked-lists">Circular linked lists</h3>
<p>With circular linked lists, we have the last node also pointing to the first element, creating circularity.</p>
<p>We'll only look at the singly circular linked list for simplicity's sake, so our node will look the same as in the first example:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Node</span> </span>{
  <span class="hljs-keyword">constructor</span>(data) {
    <span class="hljs-built_in">this</span>.data = data;
    <span class="hljs-built_in">this</span>.next = <span class="hljs-literal">null</span>;
  }
}
</code></pre>
<p>The same example, in a circular linked list fashion:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747915538225/ea4341cb-2a39-4728-b833-362455a51cdd.gif" alt="Animated visualization of a circular linked list, nodes having 1, 2, and 3 as values." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>Here is a simple implementation:</p>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CircularLinkedList</span> </span>{
  <span class="hljs-keyword">constructor</span>() {
    <span class="hljs-built_in">this</span>.head = <span class="hljs-literal">null</span>;
    <span class="hljs-built_in">this</span>.tail = <span class="hljs-literal">null</span>;
    <span class="hljs-built_in">this</span>.length = <span class="hljs-number">0</span>;
  }

  <span class="hljs-comment">// Add value to the "end" of the list</span>
  append(value) {
    <span class="hljs-keyword">let</span> node = <span class="hljs-keyword">new</span> Node(value);
    <span class="hljs-comment">// If the list is empty</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head === <span class="hljs-literal">null</span>) {
      <span class="hljs-built_in">this</span>.head = node;
      <span class="hljs-built_in">this</span>.tail = node;
      <span class="hljs-comment">// As the only node in the list, it should point to itself</span>
      node.next = node;
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-comment">// As the "last" node, it should point to the head (this.tail.next)</span>
      node.next = <span class="hljs-built_in">this</span>.tail.next;
      <span class="hljs-built_in">this</span>.tail.next = node;
      <span class="hljs-built_in">this</span>.tail = node;
    }

    <span class="hljs-built_in">this</span>.length++;
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>;
  }

  <span class="hljs-comment">// Add value to the beginning of the list</span>
  prepend(value) {
    <span class="hljs-keyword">let</span> node = <span class="hljs-keyword">new</span> Node(value);
    node.next = <span class="hljs-built_in">this</span>.head;
    <span class="hljs-comment">// Update last node's next pointer to point to the new node</span>
    <span class="hljs-built_in">this</span>.tail.next = node;
    <span class="hljs-built_in">this</span>.head = node;
    <span class="hljs-built_in">this</span>.length++;
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>;
  }  

  remove(value) {
    <span class="hljs-comment">// If the list is empty, return null</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head === <span class="hljs-literal">null</span>) { 
      <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>; 
    }

    <span class="hljs-comment">// If it is the first element</span>
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head.data === value) {
      <span class="hljs-comment">// If it's the only element</span>
      <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head.next === <span class="hljs-built_in">this</span>.head) {
        <span class="hljs-built_in">this</span>.head = <span class="hljs-literal">null</span>;
        <span class="hljs-built_in">this</span>.tail = <span class="hljs-literal">null</span>;
        <span class="hljs-keyword">return</span>;
      }
      <span class="hljs-built_in">this</span>.head = <span class="hljs-built_in">this</span>.head.next;
      <span class="hljs-built_in">this</span>.tail.next = <span class="hljs-built_in">this</span>.head;
      <span class="hljs-built_in">this</span>.length--;
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-keyword">let</span> currentNode = <span class="hljs-built_in">this</span>.head;
    <span class="hljs-keyword">let</span> prevNode = <span class="hljs-literal">null</span>;

    <span class="hljs-comment">// Iterate until you find the value or</span>
    <span class="hljs-comment">// you don't find it after traversing the whole list</span>
    <span class="hljs-keyword">while</span> (currentNode.data !== value || prevNode === <span class="hljs-literal">null</span>) {
      <span class="hljs-keyword">if</span> (currentNode.next === <span class="hljs-built_in">this</span>.head) { 
        <span class="hljs-keyword">break</span>; 
      }
      prevNode = currentNode;
      currentNode = currentNode.next;
    }

    <span class="hljs-keyword">if</span> (currentNode.data === value) {
      <span class="hljs-comment">// If there is a previous node before the element to be removed,</span>
      <span class="hljs-comment">// update the previous node's next pointer to point to</span>
      <span class="hljs-comment">// the one after the element to be removed</span>
      <span class="hljs-comment">// (unlink it)</span>
      <span class="hljs-keyword">if</span> (prevNode) {
        prevNode.next = currentNode.next;
        <span class="hljs-comment">// If the element to be removed is the last one,</span>
        <span class="hljs-comment">// update tail to be the previous node</span>
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.tail === currentNode) {
          <span class="hljs-built_in">this</span>.tail = prevNode;
        }
      <span class="hljs-comment">// If the element to be removed is the first one in the list</span>
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-comment">// If it's the only one in the list</span>
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head.next === <span class="hljs-built_in">this</span>.head) {
          <span class="hljs-built_in">this</span>.head = <span class="hljs-literal">null</span>;
          <span class="hljs-built_in">this</span>.tail = <span class="hljs-literal">null</span>;
        } <span class="hljs-keyword">else</span> {
          <span class="hljs-built_in">this</span>.head = <span class="hljs-built_in">this</span>.head.next;
          <span class="hljs-built_in">this</span>.tail.next = <span class="hljs-built_in">this</span>.head;
        }
      }
    }
  }

  printList() {
    <span class="hljs-keyword">let</span> nodes = [];
    <span class="hljs-keyword">let</span> currentNode = <span class="hljs-built_in">this</span>.head;
    <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.head === <span class="hljs-literal">null</span>) { 
      <span class="hljs-built_in">console</span>.log(nodes); 
      <span class="hljs-keyword">return</span>;
    }

    <span class="hljs-comment">// Traverse the list once to add the values, </span>
    <span class="hljs-comment">// don't go in circles</span>
    <span class="hljs-keyword">do</span> {
      nodes.push(currentNode.data);
      currentNode = currentNode.next;
    } <span class="hljs-keyword">while</span> (currentNode !== <span class="hljs-built_in">this</span>.head);

    <span class="hljs-built_in">console</span>.log(nodes);
  }
}
</code></pre>
<h4 id="heading-time-and-space-complexity-6">Time and space complexity</h4>
<p>With linked lists, the time complexity for accessing an element is in the worst case \(O(n)\). <em>Prepending</em> and <em>appending</em> an element depends on whether we have a tail pointer. If we have it, then both operations are \(O(1)\), as we only need to arrange pointers. But if we don't have a tail pointer, <em>appending</em> an element requires traversing the whole list, so it is an \(O(n)\) operation. Removing an element is similar – in the worst case, it is \(O(n)\).</p>
<p>If the space complexity is linear – \(O(n)\)– then the amount of data to store grows linearly with the number of nodes in the list.</p>
<h2 id="heading-interlude-fast-amp-slow-pointers">Interlude: Fast &amp; Slow Pointers</h2>
<p>Let's take a quick look at a technique that comes in handy when it comes to working with linked lists.</p>
<p>We can keep two pointers while traversing a linked list: fast and slow. While the fast one increases by two steps, the slow pointer will increase by just one step.</p>
<h3 id="heading-finding-the-middle-node-of-a-linked-list">Finding the middle node of a linked list</h3>
<p>When the fast pointer reaches the end of the list, the slow pointer will be at the "middle" node.</p>
<p>Let's see how it might work:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> slow = head;
<span class="hljs-keyword">let</span> fast = head;

<span class="hljs-keyword">while</span> (fast !== <span class="hljs-literal">null</span> &amp;&amp; fast.next !== <span class="hljs-literal">null</span>) {
  slow = slow.next;
  fast = fast.next.next;
}
</code></pre>
<p>We can think of a list like <code>[1, 2, 3, 4, 5]</code> (where each value is a node in the linked list).</p>
<p>Both <code>fast</code> and <code>slow</code> start pointing to the head, that is, <code>1</code>.</p>
<p>Then, we update the slow pointer one step, which will be <code>2</code>. And, <code>fast</code> will be at <code>3</code>.</p>
<p>When we update <code>slow</code> again, it will be at <code>3</code>. When the fast pointer increases, it will be two steps ahead, and its <code>next</code> pointer will point to the <code>null</code> value, at which point our loop will stop iterating.</p>
<p><code>slow</code> will end up pointing to the node with the value <code>3</code>, which is the middle node.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747915833404/d3c562e8-36e3-459f-a29c-860e0d4869f0.gif" alt="Animated visualization of fast and slow pointers technique on a linked list of 5 nodes." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>With an even number of nodes, there are two candidates for the middle node. For example, with a list like <code>[1, 2, 3, 4]</code>, our current implementation will find the middle as <code>3</code>. This technique is also useful to detect cycles in a linked list.</p>
<h2 id="heading-chapter-seven-trees">Chapter Seven: Trees</h2>
<p>Let’s take a look at a non-linear data structure that is pretty familiar to many developers: trees.</p>
<p>Whether familiarity breeds contempt or not is arguable, so let's start with the simplest component of a tree: a node.</p>
<p>Trees, like linked lists, are made up of nodes. The simplest version of a tree is just the <strong>root node</strong> which doesn't have any edges (links) pointing to it; that is, it has no <strong>parent nodes</strong>. It is the starting point, in a way.</p>
<p>A tree can only have one root node, and when you think about it, <em>if there are</em> \(n\) <em>nodes in a tree, that means there are</em> \(n - 1\) <em>edges (links)</em> because there is no edge (link) pointing to the root node.</p>
<p>If you've looked at a tree long enough, you might've had a moment of epiphany: a tree has smaller trees within itself. A branch may as well be a trunk, having other branches for the little tree it constitutes.</p>
<p>The tree data structure is like this, it is recursive: <em>a child node can be the root of a subtree</em>.</p>
<p>Two terms that are important when it comes to a tree node are <strong>depth</strong> and <strong>height</strong>.</p>
<p>The <strong>depth</strong> of a node is how far away it is from the root node (how many edges (links) does it take to travel from the root node to it), and the <strong>height</strong> of a node is how far away it is from its furthest <strong>leaf node</strong> (which is a node that has no children).</p>
<p><strong>Note:</strong> The height of the root node is the same as the height of the whole tree.</p>
<p>A <strong>balanced tree</strong> is one where <em>the heights of the left and right subtrees of every node differ by at most 1</em>.</p>
<h3 id="heading-binary-trees-binary-search-trees-bsts">Binary trees, binary search trees (BSTs)</h3>
<p>A <strong>binary tree</strong> is a tree where each node has at most two children. That is, a node can have a left child node and a right child node, and no more.</p>
<p>The maximum number of nodes in a binary tree is \(2^h - 1\) where \(h\) is the height of the tree. This is where the <em>binary</em> of the binary tree makes sense: on each level, the number of nodes grows proportionately to the exponents of \(2\).</p>
<p>For example, the number of nodes on the first level (the 0th level) is \(2^0 = 1\), which is just the root node. The second level has at most 2 nodes: \(2^1 = 2\) (remember that we're counting from \(0\), so the second level is \(1\)).</p>
<p>A <strong>binary search tree</strong> is a binary tree where the values smaller than the node go to its left and those greater than it go to its right:</p>
<p>$$\text{left children } \lt \text{ node } \lt \text{ right children}$$</p><p>Here is an example:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747916761231/c0b5301c-6832-43a9-8abd-30f578ac2a29.gif" alt="Animated visualization of a binary search tree with 8 as the root node, 3 as its left child, 10 as its right child. 3 has 1 as it left child, 6 as its right child. 6 has 4 as its left child, 7 as its right child. 10 has 14 as its right child. 14 has 13 as its left child. " class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>We can define a tree node like this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> TreeNode {
  val: <span class="hljs-built_in">number</span>;
  left: TreeNode | <span class="hljs-literal">null</span>;
  right: TreeNode | <span class="hljs-literal">null</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">val: <span class="hljs-built_in">number</span>, left?: TreeNode | <span class="hljs-literal">null</span>, right?: TreeNode | <span class="hljs-literal">null</span></span>) {
    <span class="hljs-built_in">this</span>.val = val;
    <span class="hljs-built_in">this</span>.left = (left === <span class="hljs-literal">undefined</span> ? <span class="hljs-literal">null</span> : left);
    <span class="hljs-built_in">this</span>.right = (right === <span class="hljs-literal">undefined</span> ? <span class="hljs-literal">null</span> : right);
  }
}
</code></pre>
<h4 id="heading-inserting-into-a-binary-search-tree">Inserting into a binary search tree</h4>
<p>If we want to insert a new node into a binary search tree, we need to insert it into its proper place to keep the properties of a BST intact.</p>
<h5 id="heading-recursive-solution">Recursive solution:</h5>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">insertIntoBST</span>(<span class="hljs-params">root: TreeNode | <span class="hljs-literal">null</span>, val: <span class="hljs-built_in">number</span></span>) </span>{
  <span class="hljs-keyword">if</span> (root === <span class="hljs-literal">null</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> TreeNode(val);
  }

  <span class="hljs-keyword">if</span> (val &lt; root.val) {
    root.left = insertIntoBST(root.left, val);
  } <span class="hljs-keyword">else</span> {
    root.right = insertIntoBST(root.right, val);
  }

  <span class="hljs-keyword">return</span> root;
}
</code></pre>
<p>Here, we traverse the tree until we find a space (a <code>null</code> position) for our value that is waiting to be a <code>TreeNode</code>. We start with the root node. If the value of the node-to-be-inserted is less than the value of the root node, we go left (passing <code>root.left</code> as the <code>root</code> argument to the function). Otherwise, we go right (passing <code>root.right</code> as the <code>root</code> argument).</p>
<h4 id="heading-time-and-space-complexity-7">Time and space complexity</h4>
<p>The time complexity is \(O(h)\) where \(h\) is the height of the tree. On each level in the tree, we either go left or right, so we don't necessarily visit every single node. The space complexity is also \(O(h)\) because we use recursion, creating a new stack frame for each function call.</p>
<p><em>Note that if the tree is unbalanced, the time and space complexity can be said to be</em> \(O(n)\)<em>.</em></p>
<h5 id="heading-iterative-solution">Iterative solution:</h5>
<p>We can also do it iteratively, using pointers only:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">insertIntoBST</span>(<span class="hljs-params">root: TreeNode | <span class="hljs-literal">null</span>, val: <span class="hljs-built_in">number</span></span>) </span>{
  <span class="hljs-keyword">if</span> (root === <span class="hljs-literal">null</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> TreeNode(val);
  }

  <span class="hljs-keyword">let</span> prevNode: TreeNode | <span class="hljs-literal">null</span> = <span class="hljs-literal">null</span>;
  <span class="hljs-keyword">let</span> currentNode: TreeNode | <span class="hljs-literal">null</span> = root;

  <span class="hljs-keyword">while</span> (currentNode !== <span class="hljs-literal">null</span>) {
    prevNode = currentNode;
    <span class="hljs-keyword">if</span> (val &lt; currentNode.val) {
      currentNode = currentNode.left;
    } <span class="hljs-keyword">else</span> {
      currentNode = currentNode.right;
    }
  }

  <span class="hljs-keyword">if</span> (prevNode) {
    <span class="hljs-keyword">if</span> (val &lt; prevNode.val) {
      prevNode.left = <span class="hljs-keyword">new</span> TreeNode(val);
    } <span class="hljs-keyword">else</span> {
      prevNode.right = <span class="hljs-keyword">new</span> TreeNode(val);
    }
  }

  <span class="hljs-keyword">return</span> root;
}
</code></pre>
<p>Here, we do the same thing: iterating until we find the correct place, but also keeping track of the parent node. Then, we insert the node as either the left or the right child of the parent, depending on its value.</p>
<h4 id="heading-time-and-space-complexity-8">Time and space complexity</h4>
<p>The time complexity is again \(O(h)\) (<em>or if the tree is unbalanced,</em> \(O(n)\)) for the same reason as in the recursive solution. But the space complexity is constant – \(O(1)\) – as we only use pointers.</p>
<h4 id="heading-deleting-from-a-binary-search-tree">Deleting from a binary search tree</h4>
<p>The challenging thing when deleting a node from a BST is keeping the BST as a BST. All smaller values should still go to the root node's left subtree, and all those that are larger should go to the root node's right subtree.</p>
<p>Let's take a look at how we might do it in JavaScript:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">deleteNode</span>(<span class="hljs-params">root: TreeNode | null, key: number</span>) </span>{
  <span class="hljs-keyword">if</span> (root === <span class="hljs-literal">null</span>) {
    <span class="hljs-keyword">return</span> root;
  }

  <span class="hljs-keyword">if</span> (key &lt; root.val) {
    root.left = deleteNode(root.left, key);
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (key &gt; root.val) {
    root.right = deleteNode(root.right, key);
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// Node-to-be-deleted has no children</span>
    <span class="hljs-keyword">if</span> (root.left === <span class="hljs-literal">null</span> &amp;&amp; root.right === <span class="hljs-literal">null</span>) {
      <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
    } 

    <span class="hljs-comment">// If either the left or the right child exists,</span>
    <span class="hljs-comment">// return the one that exists as the new child </span>
    <span class="hljs-comment">// of the parent node (of the node-to-be-deleted)</span>
    <span class="hljs-keyword">if</span> (root.left === <span class="hljs-literal">null</span> || root.right === <span class="hljs-literal">null</span>) {
      <span class="hljs-keyword">return</span> root.left ? root.left : root.right;
    }

    <span class="hljs-comment">// If both children exist, traverse the left subtree, get its maximum value...</span>
    <span class="hljs-keyword">let</span> currentNode = root.left;

    <span class="hljs-keyword">while</span> (currentNode.right !== <span class="hljs-literal">null</span>) {
      currentNode = currentNode.right;
    }

    <span class="hljs-comment">// ...replace it with the node-to-be-deleted</span>
    root.val = currentNode.val;
    <span class="hljs-comment">// ...then apply the recursion to the left subtree to get rid of the duplicate value</span>
    root.left = deleteNode(root.left, root.val);
  }

  <span class="hljs-keyword">return</span> root;
}
</code></pre>
<p>We traverse the tree until we find the node to be deleted. Once we find it, there are several things to do.</p>
<p>In the case where it doesn't have any child nodes, we can return <code>null</code> and be done with it.</p>
<p>If it has one child node, we can return the one that exists using the ternary operation (<code>return root.left ? root.left : root.right</code>).</p>
<p><strong>Note:</strong> <em>In this case, we're essentially making the root of the subtree the child of the parent node.</em></p>
<p>For example, in the image, if the node-to-be-deleted is 10 (it has only right child node with the value 14), we make 14 the right child of 8. It doesn't break our BST, because those that are larger than 8 continue to be in the right subtree of 8:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747918477656/7a66ad05-3c93-4482-987e-399f65e9dc57.png" alt="A binary tree that has the value 8 as its root node. It has a left child with the value 3 and a right child with the value 10. The left child has a left child node that has the value 1 and a right child node that has the value 6, which has a left child node with the value 4 and a right child node with the value 7. The right child of the root node that has the value 10 has a right child node with value 14, which has a left child node that has the value 13." class="image--center mx-auto" width="876" height="830" loading="lazy"></p>
<p>Otherwise, if both the left and right children of the node-to-be-deleted exist, we need to do something different.</p>
<p>In this case, we'll replace the node-to-be-deleted with the largest value in the left subtree.</p>
<p>But, after replacing, we'll have two nodes of the same value in both places, so we need to apply <code>deleteNode</code> itself to the subtree that we've taken our replacement node from.</p>
<p>This is all done to keep the BST as BST. It might be a bit difficult to wrap your head around at first, but <a target="_blank" href="https://www.youtube.com/watch?v=LFzAoJJt92M">NeetCode has a detailed explanation of this problem</a>.</p>
<p><strong>Note</strong> that we can also use the smallest value in the right subtree as well. In that case, our code would look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> currentNode = root.right;

<span class="hljs-keyword">while</span> (currentNode.left !== <span class="hljs-literal">null</span>) {
  currentNode = currentNode.left;
}

root.val = currentNode.val;
root.right = deleteNode(root.right, root.val);
</code></pre>
<h4 id="heading-time-and-space-complexity-9">Time and space complexity</h4>
<p>Similar to inserting into a BST, both the time and space complexity of deleting from a BST will be \(O(h)\) where \(h\) is the height of the tree.</p>
<h4 id="heading-traversals">Traversals</h4>
<p>We'll take a brief look at two of the most famous ways to traverse a tree where the order in which we visit the nodes matters: depth-first search and breadth-first search.</p>
<h5 id="heading-1-depth-first-search-dfs">1. Depth-First Search (DFS)</h5>
<p>In a depth-first search, we traverse through a branch until we get to a leaf node. Then, we backtrack and do the same thing with another branch.</p>
<p>There are three common ways to do a depth-first search:</p>
<ul>
<li><p>preorder traversal</p>
</li>
<li><p>inorder traversal</p>
</li>
<li><p>postorder traversal</p>
</li>
</ul>
<h6 id="heading-preorder-traversal">Preorder traversal:</h6>
<p>It goes like this: We first visit the node, then go on to its left subtree, then the right subtree.</p>
<p><strong>node ➞ left subtree ➞ right subtree</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747918872908/dedfc341-d32e-4558-abd6-00ff8d67b46f.gif" alt="Animated visualization of the same binary search tree displaying preorder traversal, with highlighted nodes in this order: 8, 3, 1, 6, 4, 7, 10, 14, 13." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>We can do a preorder walk recursively:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">preorderWalk</span>(<span class="hljs-params">node</span>) </span>{
  <span class="hljs-keyword">if</span> (node === <span class="hljs-literal">null</span>) {
    <span class="hljs-keyword">return</span>;
  }

  <span class="hljs-built_in">console</span>.log(node.val);
  preorderWalk(node.left);
  preorderWalk(node.right);
}
</code></pre>
<h6 id="heading-inorder-traversal">Inorder traversal:</h6>
<p>It goes like this: we first visit the left subtree, then the node, then the right subtree.</p>
<p><strong>left subtree ➞ node ➞ right subtree</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747918945108/a1ff3284-8aa0-4815-928c-99cdbd8ac956.gif" alt="Animated visualization of the same binary search tree displaying inorder traversal, with highlighted nodes in this order: 1, 3, 4, 6, 7, 8, 10, 13, 14." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p><strong>Note:</strong> The inorder traversal gives us the sorted values.</p>
<p>We can do an inorder walk recursively as well:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">inorderWalk</span>(<span class="hljs-params">node</span>) </span>{
  <span class="hljs-keyword">if</span> (node === <span class="hljs-literal">null</span>) {
    <span class="hljs-keyword">return</span>;
  }

  inorderWalk(node.left);
  <span class="hljs-built_in">console</span>.log(node.val);
  inorderWalk(node.right);
}
</code></pre>
<h6 id="heading-postorder-traversal">Postorder traversal:</h6>
<p>It goes like this: we first visit the left subtree, then the right subtree, and finally the node.</p>
<p><strong>left subtree ➞ right subtree ➞ node</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747919023258/e3c7f4a3-3ec8-47d3-aa49-e8f4b0f8d30a.gif" alt="Animated visualization of the same binary search tree displaying postorder traversal, with highlighted nodes in this order: 1, 4, 7, 6, 3, 13, 14, 10, 8." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>We can do a postorder walk recursively:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">postorderWalk</span>(<span class="hljs-params">node</span>) </span>{
  <span class="hljs-keyword">if</span> (node === <span class="hljs-literal">null</span>) {
    <span class="hljs-keyword">return</span>;
  }

  postorderWalk(node.left);
  postorderWalk(node.right);
  <span class="hljs-built_in">console</span>.log(node.val);
}
</code></pre>
<h5 id="heading-2-breadth-first-search-bfs">2. Breadth-First Search (BFS)</h5>
<p>In breadth-first search, we visit the nodes level by level, that is, visiting every child of a node first before moving on.</p>
<p>A queue is used when implementing a BFS. Since we don't have edges connecting all the children on one level together, it makes sense to keep them in a queue and visit each one when their time comes. When a node is added to the queue and has not been visited yet, it's called a <strong>discovered node</strong>.</p>
<p>A simple BFS operation looks like this (which is repeated until the queue is empty):</p>
<ul>
<li><p>visit node</p>
</li>
<li><p>enqueue left child</p>
</li>
<li><p>enqueue right child</p>
</li>
</ul>
<p>Note that the breadth-first search is also known as <em>level-order traversal</em>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747919081789/17beb70f-7302-4f32-9a9a-72d69e190ac9.gif" alt="Animated visualization of the same binary search tree displaying level-order traversal, with highlighted nodes in this order: 8, 3, 10, 1, 6, 14, 4, 7, 13." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>A simple example of a level-order traversal in JavaScript might look like this:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">levelOrderWalk</span>(<span class="hljs-params">root</span>) </span>{
  <span class="hljs-keyword">if</span> (root === <span class="hljs-literal">null</span>) {
    <span class="hljs-keyword">return</span>;
  }

  <span class="hljs-keyword">let</span> queue = [];
  queue.push(root);

  <span class="hljs-keyword">while</span> (queue.length &gt; <span class="hljs-number">0</span>) {
    <span class="hljs-keyword">let</span> currentNode = queue[<span class="hljs-number">0</span>];

    <span class="hljs-built_in">console</span>.log(currentNode.val);

    <span class="hljs-keyword">if</span> (currentNode.left !== <span class="hljs-literal">null</span>) {
      queue.push(currentNode.left);
    }

    <span class="hljs-keyword">if</span> (currentNode.right !== <span class="hljs-literal">null</span>) {
      queue.push(currentNode.right);
    }

    <span class="hljs-comment">// Remove the current node</span>
    queue.shift();
  }
}
</code></pre>
<p>This example is based on Vaidehi Joshi's <a target="_blank" href="https://gist.github.com/vaidehijoshi/27f9fa6b6b68f70360019805b5ca3692#file-level_order_search-js">GitHub Gist</a>.</p>
<h2 id="heading-chapter-eight-heap-priority-queue">Chapter Eight: Heap / Priority Queue</h2>
<p>It’s now time to take a look at a data structure called a <em>heap</em>, which is a great way to implement an <a target="_blank" href="https://en.wikipedia.org/wiki/Abstract_data_type">abstract data type</a> called a <strong>priority queue</strong>. They're so interrelated that priority queues are sometimes referred to as heaps – because heaps are a very efficient way to create a priority queue.</p>
<h3 id="heading-heap-properties">Heap properties</h3>
<p>The kind of heap we're interested in is also called a <strong>binary heap</strong> because it's just a binary tree that has specific properties.</p>
<p>One of them is that it must be a <strong>complete binary tree</strong>, meaning that all the levels must be filled, and <em>all nodes in the last level should be as far left as possible</em>.</p>
<p>For example, when it comes to shape, this is a complete binary tree:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747919274226/cdc2f987-3327-4220-8584-ad3999ea7f39.gif" alt="Animated visualization of a tree with root node having two children, both of its left and right children having two children their own. The left child of the left child has only a left child on its own." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>But heaps must also be either a <strong>max heap</strong> or a <strong>min heap</strong> – all the parent nodes must be either greater than or equal to the values of their children (if it's a max heap) or less than or equal to the values of their children (if it's a min heap).</p>
<p>A max heap might look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747919301787/6a3b30cd-a686-4112-80a9-0249c7597751.gif" alt="Animated visualization of a max heap, having 42 at the top, 19 at its left, 36 at its right. 19 has 17 at its left, 3 at its right. 36 has 25 at its left, 1 at its right. 17 has 2 at its left." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p><strong>Note:</strong> A left child doesn't have to be less than the right child at all, as in a binary search tree. Also, we can always have duplicate values in a heap.</p>
<p>A min heap, on the other hand, has the values of parent nodes less than those of their children:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747919335031/b5b82848-ac1f-405d-9124-725a9c26af55.gif" alt="Animated visualization of a min heap, having 1 at the top, 2 at its left, 3 at its right. 2 has 17 at its left, 19 at its right. 3 has 36 at its left, 7 at its right. 17 has 42 at its left." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p><strong>Note:</strong> When we have a max heap, the root node will have the maximum value. And, if we have a min heap instead, the root node will have the minimum value.</p>
<h3 id="heading-heaps-with-arrays">Heaps with arrays</h3>
<p>We can create a heap using an array. Since the root node is the most interesting element with either a maximum or minimum value, it'll be the first element in our array, residing at the 0th index.</p>
<p>What's nice about using an array is that, given a parent node's index \(i\), its left child will be at the index \(2i + 1\), and its right child will be at the index \(2i + 2\).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747919415922/b98a55a9-f9cc-4e11-8d53-f5a8a411d861.gif" alt="Animated visualization of the max heap above implemented as an array. A left child's index corresponds to 2i+1, a right child's index corresponds to 2i+2." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>Given that, any child node's parent will be at the index \(\lfloor{\frac{(n - 1)}{2}}\rfloor\).</p>
<p><strong>Note:</strong> \(\lfloor\) and \(\rfloor\)indicate the <a target="_blank" href="https://en.wikipedia.org/wiki/Floor_and_ceiling_functions">floor function</a>.</p>
<p>One question we might ask at this moment is that why should we use an array at all?</p>
<p>The answer lies in the word <strong>queue</strong> of a <strong>priority queue</strong>. Since a queue is mainly concerned with the first element (following the <a target="_blank" href="https://en.wikipedia.org/wiki/FIFO_\(computing_and_electronics\)">FIFO principle</a>), an array can be an ideal choice. In a priority queue, each element has a priority, and the value with the highest priority is dequeued first.</p>
<h3 id="heading-insertingremoving-elements">Inserting/removing elements</h3>
<p>Let's take a look at how we can add an element to a heap.</p>
<p>We know that we have to add the new element to the bottom leftmost place, but once we do that, it might violate the max heap or the min heap property. Then, how can we avoid violating the <strong>heap-order property</strong>?</p>
<p>We'll <strong>heapify</strong>, of course!</p>
<p>Let's say that we want to add a node with the value <code>20</code>:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747919523941/eb0959dd-fcf8-4fb7-9ebf-938fde24ba10.gif" alt="Animated visualization of the max heap above. A new item 20 is first inserted at the leftest possible place. Then it swaps places with 17 and then 19, coming to the left of 42." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>So, heapify is the swapping of nodes until we know that the heap-order property is maintained.</p>
<p>A similar thing happens when we need to remove an element. But since we're mainly concerned with the maximum or the minimum element, we just need to remove the root node. So, how are we going to do that?</p>
<p>We start off by swapping the last element (the bottom leftmost one) with the root. Now we can easily remove the "root," which resides as a leaf node. But we still need to maintain the heap-order property, so we need to <strong>heapify</strong> again.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747919564248/0e7b9a38-6b23-4448-a804-cf095d16f30e.gif" alt="Animated visualization of the max heap above. 2 swapping places with 42, 42 being disappeared. 2 later swaps places with 36 and 25, now 36 coming to the top." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<h3 id="heading-heapsort">Heapsort</h3>
<p>Even better thing is that if we have a heap, and continually heapify it, we can sort an array.</p>
<p>Let's build a max heap first:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">buildMaxHeap</span>(<span class="hljs-params">arr: <span class="hljs-built_in">number</span>[]</span>) </span>{
  <span class="hljs-comment">/*
  Index of the last internal node 
  (i.e., the parent of the last leaf node, 
   or, the last non-leaf node).
  The last leaf node will reside at index arr.length - 1,
  so, we're getting its parent using the formula mentioned above.
  */</span>
  <span class="hljs-keyword">let</span> i = <span class="hljs-built_in">Math</span>.floor((arr.length - <span class="hljs-number">1</span>) / <span class="hljs-number">2</span>);

  <span class="hljs-keyword">while</span> (i &gt;= <span class="hljs-number">0</span>) {
    heapify(arr, i, arr.length);
    i--;
  }

  <span class="hljs-keyword">return</span> arr;
}
</code></pre>
<p>Then, the <code>heapify</code> function:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">heapify</span>(<span class="hljs-params">arr: <span class="hljs-built_in">number</span>[], i: <span class="hljs-built_in">number</span>, maxLength: <span class="hljs-built_in">number</span></span>) </span>{
  <span class="hljs-keyword">while</span> (i &lt; maxLength) {
    <span class="hljs-keyword">let</span> index = i;
    <span class="hljs-keyword">let</span> leftChildIdx = <span class="hljs-number">2</span> * i + <span class="hljs-number">1</span>;
    <span class="hljs-keyword">let</span> rightChildIdx = leftChildIdx + <span class="hljs-number">1</span>;

    <span class="hljs-keyword">if</span> (leftChildIdx &lt; maxLength &amp;&amp; arr[leftChildIdx] &gt; arr[index]) {
      index = leftChildIdx;
    }

    <span class="hljs-keyword">if</span> (rightChildIdx &lt; maxLength &amp;&amp; arr[rightChildIdx] &gt; arr[index]) {
      index = rightChildIdx;
    }

    <span class="hljs-keyword">if</span> (index === i) { <span class="hljs-keyword">return</span>; }

    <span class="hljs-comment">// Swap</span>
    [arr[i], arr[index]] = [arr[index], arr[i]];

    i = index;
  }
}
</code></pre>
<p>With a given index <code>i</code>, we get its left and right children indices, and if the indices are within bounds, we check if they are out of order. In that case, we make the <code>index</code> the index of the child, and swap the two nodes. Then, we continue with that new index, assigning it to <code>i</code>.</p>
<p>Now, <code>heapify</code> is nice and all, but how can we actually use it for sorting?</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">heapSort</span>(<span class="hljs-params">arr: <span class="hljs-built_in">number</span>[]</span>) </span>{
  buildMaxHeap(arr);

  <span class="hljs-keyword">let</span> lastElementIdx = arr.length - <span class="hljs-number">1</span>;

  <span class="hljs-keyword">while</span> (lastElementIdx &gt; <span class="hljs-number">0</span>) {
    [arr[<span class="hljs-number">0</span>], arr[lastElementIdx]] = [arr[lastElementIdx], arr[<span class="hljs-number">0</span>]];

    heapify(arr, <span class="hljs-number">0</span>, lastElementIdx);
    lastElementIdx--;
  }

  <span class="hljs-keyword">return</span> arr;
}
</code></pre>
<p><strong>Note</strong> that our max heap <code>[42, 19, 36, 17, 3, 25, 1, 2]</code> won't change when used in the <code>buildMaxHeap</code> function, as it's already a max heap! But if it were to have <code>17</code> as the right child of <code>42</code>, then <code>17</code> would have <code>25</code> as a child, which breaks the heap-order property. So, using <code>buildMaxHeap</code> with this broken version will correctly swap the <code>17</code> and <code>25</code>, making it a max heap:</p>
<pre><code class="lang-typescript">buildMaxHeap([<span class="hljs-number">42</span>, <span class="hljs-number">36</span>, <span class="hljs-number">17</span>, <span class="hljs-number">19</span>, <span class="hljs-number">3</span>, <span class="hljs-number">25</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>]);

<span class="hljs-comment">// -&gt; [42, 36, 25, 19, 3, 17, 1, 2]</span>
</code></pre>
<p>In <code>heapSort</code>, with our newly built max heap, we'll start with swapping the first and last nodes. Then, we'll keep heapifying until we get all the elements in their place. If we use it with our very own max heap, we can see that it returns the sorted array:</p>
<pre><code class="lang-typescript">heapSort([<span class="hljs-number">42</span>, <span class="hljs-number">19</span>, <span class="hljs-number">36</span>, <span class="hljs-number">17</span>, <span class="hljs-number">3</span>, <span class="hljs-number">25</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>]);
<span class="hljs-comment">// -&gt; [1, 2, 3, 17, 19, 25, 36, 42]</span>
</code></pre>
<p>The examples are adapted from <a target="_blank" href="https://medium.com/basecs/heapify-all-the-things-with-heap-sort-55ee1c93af82">Vaidehi Joshi's article</a>.</p>
<h4 id="heading-time-and-space-complexity-10">Time and space complexity</h4>
<p>Heap sort, as a nice sorting algorithm it is, runs in \(O(n \ log \ n)\) time.</p>
<p>In this example, building the max heap starts from the last non-leaf node and goes up to the root node, each time calling <code>heapify</code>. The <code>heapify</code> function has a time complexity of \(O(log \ n)\) as we're working with a binary tree, and in the worst case, we get to do it for all the levels. Since we do it \(n / 2\) times, overall, <code>buildMaxHeap</code> has \(O(n \ log \ n)\) time complexity.</p>
<p>We're swapping the first and last elements, and heapifying as we go through each element, so this is also overall an \(O(n \ log \ n)\) operation — which makes the time complexity of <code>heapSort</code> \(O(n \ log \ n)\)<em>.</em></p>
<p><strong>Note:</strong> Building the max heap <a target="_blank" href="https://stackoverflow.com/questions/9755721/how-can-building-a-heap-be-on-time-complexity">can be improved to have</a> \(O(n)\) <a target="_blank" href="https://stackoverflow.com/questions/9755721/how-can-building-a-heap-be-on-time-complexity">runtime</a>.</p>
<p>Since there is no use of auxiliary space, the space complexity is constant, \(O(1)\).</p>
<h2 id="heading-chapter-nine-backtracking">Chapter Nine: Backtracking</h2>
<p>Let's start with admitting this one fact: backtracking is hard. Or rather, <em>understanding it the first time</em> is hard. Or, it's one of those concepts that you think you grasped it, only to realize later that you actually didn't.</p>
<p>We'll focus on one problem of finding the subsets of an array, but before that, let's imagine that we're walking along a path.</p>
<p>Then, we reach a fork. We pick one of the paths, and walk.</p>
<p>Then, we reach another fork in the path. We pick one of the paths again, and go on walking, then we reach a dead end. So, we <em>backtrack</em> to the last point we had a fork, then go through the other path that we didn't choose the first time.</p>
<p>Then we reach another dead end. So, we <em>backtrack</em> once more and realize that there are no other paths we can go from there. So we <em>backtrack</em> again, and explore the other path we didn't choose the first time we came to this point.</p>
<p>We reach yet another dead end, so we <em>backtrack</em>. We see that there are no more paths to explore, so we <em>backtrack</em> once more.</p>
<p>Now, we're at our starting point. There are no more paths left to explore, so we can stop walking.</p>
<p>It was a nice but tiring walk, and it went like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747920157477/3151155c-d40c-408d-bff6-5d326ad0a0f3.gif" alt="Animated visualization of the concept of backtracking." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>Now, let's take a look at a LeetCode problem.</p>
<h3 id="heading-subsets">Subsets</h3>
<p>The description for <a target="_blank" href="https://leetcode.com/problems/subsets">Subsets</a> says:</p>
<blockquote>
<p>Given an integer array <code>nums</code> of <strong>unique</strong> elements, return <em>all possible subsets (the power set)</em>.</p>
<p>The solution set <strong>must not</strong> contain duplicate subsets. Return the solution in <strong>any order</strong>.</p>
</blockquote>
<p>For example:</p>
<pre><code class="lang-plaintext">Input: nums = [1, 2, 3]
Output: [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]]
</code></pre>
<p>Or:</p>
<pre><code class="lang-plaintext">Input: nums = [0]
Output: [[], [0]]
</code></pre>
<p>Before diving into the solution code, let's take a look at how backtracking will work in this case. Let's call the <code>nums</code> array <code>items</code> instead:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747920218696/a85bf516-9bc1-4231-ab39-4a31ce1a8e6d.gif" alt="Animated visualization of backtracking for an array [1, 2, 3], exploring each possible choice." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>For each item in <code>items</code>, we have initially two choices: to include the item, or not to include it.</p>
<p>For each level \(n\) in this <em>decision tree</em>, we have the option to include the next item in <code>items</code>. We have \(2^n\) possible subsets in total.</p>
<p>Let's simplify the example a bit, and say that <code>items</code> is now <code>['a', 'b']</code> (<strong>We'll ignore the problem specifics for now</strong>).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747920275978/ab435765-7b05-4939-bd72-55dcfae7a6d4.gif" alt="Animated visualization of backtracking for an array ['a', 'b'], exploring each possible choice." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>In this case, we can use backtracking like this:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">subsets</span>(<span class="hljs-params">items: <span class="hljs-built_in">string</span>[]</span>) </span>{
  <span class="hljs-keyword">let</span> result: <span class="hljs-built_in">string</span>[][] = [];
  <span class="hljs-keyword">let</span> currentSubset: <span class="hljs-built_in">string</span>[] = [];

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">backtrack</span>(<span class="hljs-params">idx: <span class="hljs-built_in">number</span></span>) </span>{
    <span class="hljs-keyword">if</span> (idx &gt;= items.length) {
      result.push([...currentSubset]);
      <span class="hljs-keyword">return</span>;
    }

    currentSubset.push(items[idx]);
    backtrack(idx + <span class="hljs-number">1</span>);

    currentSubset.pop();
    backtrack(idx + <span class="hljs-number">1</span>);
  }

  backtrack(<span class="hljs-number">0</span>);

  <span class="hljs-keyword">return</span> result;
}

<span class="hljs-built_in">console</span>.log(subsets([<span class="hljs-string">'a'</span>, <span class="hljs-string">'b'</span>]));
<span class="hljs-comment">// -&gt; [['a', 'b'], ['a'], ['b'], []]</span>
</code></pre>
<p>Well, it looks simple at first glance, but what's going on?</p>
<p>One thing to notice is that we <code>pop</code> from the <code>currentSubset</code>, then call <code>backtrack</code>. In our example of walking, that's the part we go back to our previous point, and continue our walk.</p>
<p>In the first animation, we indicated a dead end with a cross mark, and in this case, a dead end is the <strong>base case</strong> we reach.</p>
<p>It might still be tough to understand, so let's add some helpful <code>console.log</code>s, and see the output:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">subsets</span>(<span class="hljs-params">items: <span class="hljs-built_in">string</span>[]</span>) </span>{
  <span class="hljs-keyword">let</span> result: <span class="hljs-built_in">string</span>[][] = [];
  <span class="hljs-keyword">let</span> currentSubset: <span class="hljs-built_in">string</span>[] = [];

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">backtrack</span>(<span class="hljs-params">idx: <span class="hljs-built_in">number</span></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`======= this is backtrack(<span class="hljs-subst">${<span class="hljs-built_in">arguments</span>[<span class="hljs-number">0</span>]}</span>) =======`</span>)
    <span class="hljs-keyword">if</span> (idx &gt;= items.length) {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`idx is <span class="hljs-subst">${idx}</span>, currentSubset is [<span class="hljs-subst">${currentSubset}</span>], adding it to result...`</span>);
      result.push([...currentSubset]);
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`backtrack(<span class="hljs-subst">${<span class="hljs-built_in">arguments</span>[<span class="hljs-number">0</span>]}</span>) is returning...\n`</span>)
      <span class="hljs-keyword">return</span>;
    }

    currentSubset.push(items[idx]);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`added <span class="hljs-subst">${items[idx]}</span> to currentSubset, inside backtrack(<span class="hljs-subst">${<span class="hljs-built_in">arguments</span>[<span class="hljs-number">0</span>]}</span>)`</span>);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`calling backtrack(<span class="hljs-subst">${idx + <span class="hljs-number">1</span>}</span>)...`</span>)
    backtrack(idx + <span class="hljs-number">1</span>);

    <span class="hljs-keyword">let</span> item = currentSubset.pop();
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`popped <span class="hljs-subst">${item}</span> from currentSubset, inside backtrack(<span class="hljs-subst">${<span class="hljs-built_in">arguments</span>[<span class="hljs-number">0</span>]}</span>)`</span>);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`calling backtrack(<span class="hljs-subst">${idx + <span class="hljs-number">1</span>}</span>)...`</span>)
    backtrack(idx + <span class="hljs-number">1</span>);

    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`******* done with backtrack(<span class="hljs-subst">${<span class="hljs-built_in">arguments</span>[<span class="hljs-number">0</span>]}</span>) *******\n`</span>);
  }

  backtrack(<span class="hljs-number">0</span>);

  <span class="hljs-keyword">return</span> result;
}

<span class="hljs-built_in">console</span>.log(subsets([<span class="hljs-string">'a'</span>, <span class="hljs-string">'b'</span>]));
</code></pre>
<p>The output looks like this:</p>
<pre><code class="lang-plaintext">======= this is backtrack(0) =======
added a to currentSubset, inside backtrack(0)
calling backtrack(1)...
======= this is backtrack(1) =======
added b to currentSubset, inside backtrack(1)
calling backtrack(2)...
======= this is backtrack(2) =======
idx is 2, currentSubset is [a,b], adding it to result...
backtrack(2) is returning...

popped b from currentSubset, inside backtrack(1)
calling backtrack(2)...
======= this is backtrack(2) =======
idx is 2, currentSubset is [a], adding it to result...
backtrack(2) is returning...

******* done with backtrack(1) *******

popped a from currentSubset, inside backtrack(0)
calling backtrack(1)...
======= this is backtrack(1) =======
added b to currentSubset, inside backtrack(1)
calling backtrack(2)...
======= this is backtrack(2) =======
idx is 2, currentSubset is [b], adding it to result...
backtrack(2) is returning...

popped b from currentSubset, inside backtrack(1)
calling backtrack(2)...
======= this is backtrack(2) =======
idx is 2, currentSubset is [], adding it to result...
backtrack(2) is returning...

******* done with backtrack(1) *******

******* done with backtrack(0) *******

[ [ 'a', 'b' ], [ 'a' ], [ 'b' ], [] ]
</code></pre>
<p>If you noticed, <em>Add</em> <code>'a'</code>? and <em>Go ahead?</em> arrows on the first level are calls to <code>backtrack(0)</code>.</p>
<p><em>Add</em> <code>'b'</code>? and <em>Go ahead?</em> arrows on the second level are calls to <code>backtrack(1)</code>.</p>
<p><code>backtrack(2)</code> calls are when we reach the "dead ends". In those cases, we add <code>currentSubset</code> to the <code>result</code>. We always reach the base case in a <code>backtrack(2)</code> call because it's only when the <code>idx</code> equals <code>items.length</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747920409397/0c18c7a6-1776-415b-8918-a6cafe6ba70c.gif" alt="Animated visualization of backtrack function for the array ['a', 'b']." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p><strong>Note:</strong> We modified the function in the above examples to work with strings, but in the actual solution we'll only deal with numbers, so in TypeScript, <code>result</code> and <code>currentSubset</code> will look like this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> result: <span class="hljs-built_in">number</span>[][] = [];
<span class="hljs-keyword">let</span> currentSubset: <span class="hljs-built_in">number</span>[] = [];
</code></pre>
<p>Also, the function parameter and return types are different:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">subsets</span>(<span class="hljs-params">nums: <span class="hljs-built_in">number</span>[]</span>): <span class="hljs-title">number</span>[][] </span>{ ... }
</code></pre>
<p>Otherwise, everything stays the same.</p>
<h4 id="heading-time-and-space-complexity-11">Time and space complexity</h4>
<p>A subset is, in the worst case, length \(n\) which is the length of our input. We'll have \(2^n\) subsets and since we also use a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">spread operator</a> in our example to copy <code>currentSubset</code>, the time complexity will be \(O(n \cdot 2^n)\). The space complexity is – <em>I think</em> – \(O(n \cdot 2^n)\) as well because of the recursive call stack (which is of depth <code>n</code>), and the space needed for <code>result</code> (which is in the worst case \(2^n\)).</p>
<h2 id="heading-chapter-ten-tries">Chapter Ten: Tries</h2>
<p>The trie data structure <a target="_blank" href="https://en.wikipedia.org/wiki/Trie#History,_etymology,_and_pronunciation">gets its name from the word <em>re<strong><strong>trie</strong></strong>val</em></a> – and it's usually pronounced as "try," so that we don't get confused with another familiar and friendly data structure, "tree."</p>
<p>But a trie is still a tree (or tree-like) data structure whose nodes usually store individual letters. So, by traversing the nodes in a trie, we can retrieve strings.</p>
<p>Tries are useful for applications such as autocompletion and spellchecking – and the larger our trie is, the less work we have to do for inserting a new value.</p>
<p><strong>Note:</strong> Using arrays is not very memory-efficient, but for now, we'll stick to the array implementation.</p>
<p>First, let's see what a trie looks like:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747920685051/e152eedd-75c6-478b-8291-5510b8f1421c.gif" alt="Animated visualization of a trie having the values &quot;sea&quot; and &quot;see&quot;" class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>In this trie, we can retrieve the strings "sea" and "see" – but not "sew", for example.</p>
<p>There is a lot going on, but we can try to understand it piece by piece.</p>
<p>Let's look at a trie node.</p>
<p>We'll create a <code>TrieNode</code> class that has <code>children</code>, which is an array of length 26 (so that each index corresponds to a letter in the English alphabet), and a flag variable <code>isEndOfWord</code> to indicate whether that node represents the last character of a word:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> TrieNode {
  children: (TrieNode | <span class="hljs-literal">null</span>)[];
  isEndOfWord: <span class="hljs-built_in">boolean</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">this</span>.children = <span class="hljs-built_in">Array</span>.from({ length: <span class="hljs-number">26</span> }, <span class="hljs-function">() =&gt;</span> <span class="hljs-literal">null</span>);
    <span class="hljs-built_in">this</span>.isEndOfWord = <span class="hljs-literal">false</span>;
  }
}
</code></pre>
<p>We're initializing <code>children</code> with <code>null</code> values. As we add a character to our trie, the index that corresponds to that character will be filled.</p>
<p><strong>Note:</strong> We're not storing the actual character itself in this implementation – it's implicit in the usage of indices.</p>
<p>In a trie, we start with an empty root node.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Trie {
  root: TrieNode;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">this</span>.root = <span class="hljs-keyword">new</span> TrieNode();
  }
  <span class="hljs-comment">// ...</span>
}
</code></pre>
<p>To insert a word, we're going to loop through each character, and initialize a new <code>TrieNode</code> to the corresponding index.</p>
<pre><code class="lang-typescript">insert(word: <span class="hljs-built_in">string</span>) {
  <span class="hljs-keyword">let</span> currentNode = <span class="hljs-built_in">this</span>.root;
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> char <span class="hljs-keyword">of</span> word) {
    <span class="hljs-keyword">let</span> idx = char.charCodeAt(<span class="hljs-number">0</span>) - <span class="hljs-string">'a'</span>.charCodeAt(<span class="hljs-number">0</span>);
    <span class="hljs-keyword">if</span> (currentNode.children[idx] === <span class="hljs-literal">null</span>) {
      currentNode.children[idx] = <span class="hljs-keyword">new</span> TrieNode();
    }
    currentNode = currentNode.children[idx];
  }

  currentNode.isEndOfWord = <span class="hljs-literal">true</span>;
}
</code></pre>
<p>Once we reach the node that indicates the last character of the word we inserted, we also mark the <code>isEndOfWord</code> variable as <code>true</code>.</p>
<p><strong>Note:</strong> <code>word</code> is going to be lowercase in these examples – otherwise, we have to convert it, such as:</p>
<pre><code class="lang-typescript">word = word.toLowerCase();
</code></pre>
<p>For searching a word's existence in the trie, we'll do a similar thing. We'll look at the nodes for each character, and if we reach the last one that has <code>isEndOfWord</code> marked as <code>true</code>. That means we've found the word:</p>
<pre><code class="lang-typescript">search(word: <span class="hljs-built_in">string</span>) {
  <span class="hljs-keyword">let</span> currentNode = <span class="hljs-built_in">this</span>.root;
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> char <span class="hljs-keyword">of</span> word) {
    <span class="hljs-keyword">let</span> idx = char.charCodeAt(<span class="hljs-number">0</span>) - <span class="hljs-string">'a'</span>.charCodeAt(<span class="hljs-number">0</span>);
    <span class="hljs-keyword">if</span> (currentNode.children[idx] === <span class="hljs-literal">null</span>) {
      <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
    }      
    currentNode = currentNode.children[idx];
  }

  <span class="hljs-keyword">return</span> currentNode.isEndOfWord;
}
</code></pre>
<p><strong>Note:</strong> If we find the word we're looking for, then it's called a <strong>search hit</strong>. Otherwise, we have a <strong>search miss</strong> and the word doesn't exist in our trie.</p>
<p>Removing a word is a bit more challenging. Let's say that we want to remove the word "see." But, there is also another word "sea," with the same prefix ('s' and 'e'). So, we should remove only the nodes that we're allowed to.</p>
<p>For this reason, we'll define a recursive function. Once we reach the last character of the word we want to remove, we'll back up and remove the characters we can remove:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> removeRecursively = <span class="hljs-function">(<span class="hljs-params">node: TrieNode | <span class="hljs-literal">null</span>, word: <span class="hljs-built_in">string</span>, depth: <span class="hljs-built_in">number</span></span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (node === <span class="hljs-literal">null</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
  }

  <span class="hljs-keyword">if</span> (depth === word.length) {
    <span class="hljs-keyword">if</span> (node.isEndOfWord) {
      node.isEndOfWord = <span class="hljs-literal">false</span>;
    }
    <span class="hljs-keyword">if</span> (node.children.every(<span class="hljs-function"><span class="hljs-params">child</span> =&gt;</span> child === <span class="hljs-literal">null</span>)) {
      node = <span class="hljs-literal">null</span>;
    }

    <span class="hljs-keyword">return</span> node;
  }

  <span class="hljs-keyword">let</span> idx = word[depth].charCodeAt(<span class="hljs-number">0</span>) - <span class="hljs-string">'a'</span>.charCodeAt(<span class="hljs-number">0</span>);
  node.children[idx] = removeRecursively(node.children[idx], word, depth + <span class="hljs-number">1</span>);

  <span class="hljs-keyword">if</span> (node.children.every(<span class="hljs-function"><span class="hljs-params">child</span> =&gt;</span> child === <span class="hljs-literal">null</span>) &amp;&amp; !node.isEndOfWord) {
    node = <span class="hljs-literal">null</span>;
  }

  <span class="hljs-keyword">return</span> node;
}
</code></pre>
<p><code>depth</code> indicates the index of the word, or <em>the depth of the trie we reach</em>.</p>
<p>Once <code>depth</code> is equal to the word's length (one past the last character), we check if it's the end of the word. If that's the case, we'll mark it as <code>false</code> now, because that word won't exist from here on. Then, we can only mark the node as <code>null</code> if it doesn't have any children (in other words, if all of them are <code>null</code>). We'll apply this logic to each child node recursively until the word is removed as far as it can be removed.</p>
<p>Here is the final example implementation of a trie:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> TrieNode {
  children: (TrieNode | <span class="hljs-literal">null</span>)[];
  isEndOfWord: <span class="hljs-built_in">boolean</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">this</span>.children = <span class="hljs-built_in">Array</span>.from({ length: <span class="hljs-number">26</span> }, <span class="hljs-function">() =&gt;</span> <span class="hljs-literal">null</span>);
    <span class="hljs-built_in">this</span>.isEndOfWord = <span class="hljs-literal">false</span>;
  }
}

<span class="hljs-keyword">class</span> Trie {
  root: TrieNode;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">this</span>.root = <span class="hljs-keyword">new</span> TrieNode();
  }

  insert(word: <span class="hljs-built_in">string</span>) {
    <span class="hljs-keyword">let</span> currentNode = <span class="hljs-built_in">this</span>.root;
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> char <span class="hljs-keyword">of</span> word) {
      <span class="hljs-keyword">let</span> idx = char.charCodeAt(<span class="hljs-number">0</span>) - <span class="hljs-string">'a'</span>.charCodeAt(<span class="hljs-number">0</span>);
      <span class="hljs-keyword">if</span> (currentNode.children[idx] === <span class="hljs-literal">null</span>) {
        currentNode.children[idx] = <span class="hljs-keyword">new</span> TrieNode();
      }
      currentNode = currentNode.children[idx];
    }

    currentNode.isEndOfWord = <span class="hljs-literal">true</span>;
  }

  search(word: <span class="hljs-built_in">string</span>) {
    <span class="hljs-keyword">let</span> currentNode = <span class="hljs-built_in">this</span>.root;
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> char <span class="hljs-keyword">of</span> word) {
      <span class="hljs-keyword">let</span> idx = char.charCodeAt(<span class="hljs-number">0</span>) - <span class="hljs-string">'a'</span>.charCodeAt(<span class="hljs-number">0</span>);
      <span class="hljs-keyword">if</span> (currentNode.children[idx] === <span class="hljs-literal">null</span>) {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
      }      
      currentNode = currentNode.children[idx];
    }

    <span class="hljs-keyword">return</span> currentNode.isEndOfWord;
  }

  remove(word: <span class="hljs-built_in">string</span>) {
    <span class="hljs-keyword">const</span> removeRecursively = <span class="hljs-function">(<span class="hljs-params">node: TrieNode | <span class="hljs-literal">null</span>, word: <span class="hljs-built_in">string</span>, depth: <span class="hljs-built_in">number</span></span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (node === <span class="hljs-literal">null</span>) {
        <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
      }

      <span class="hljs-keyword">if</span> (depth === word.length) {
        <span class="hljs-keyword">if</span> (node.isEndOfWord) {
          node.isEndOfWord = <span class="hljs-literal">false</span>;
        }
        <span class="hljs-keyword">if</span> (node.children.every(<span class="hljs-function"><span class="hljs-params">child</span> =&gt;</span> child === <span class="hljs-literal">null</span>)) {
          node = <span class="hljs-literal">null</span>;
        }

        <span class="hljs-keyword">return</span> node;
      }

      <span class="hljs-keyword">let</span> idx = word[depth].charCodeAt(<span class="hljs-number">0</span>) - <span class="hljs-string">'a'</span>.charCodeAt(<span class="hljs-number">0</span>);
      node.children[idx] = removeRecursively(node.children[idx], word, depth + <span class="hljs-number">1</span>);

      <span class="hljs-keyword">if</span> (node.children.every(<span class="hljs-function"><span class="hljs-params">child</span> =&gt;</span> child === <span class="hljs-literal">null</span>) &amp;&amp; !node.isEndOfWord) {
        node = <span class="hljs-literal">null</span>;
      }

      <span class="hljs-keyword">return</span> node;
    }

    removeRecursively(<span class="hljs-built_in">this</span>.root, word, <span class="hljs-number">0</span>);
  }
}

<span class="hljs-keyword">let</span> t = <span class="hljs-keyword">new</span> Trie();

t.insert(<span class="hljs-string">'sea'</span>);
t.insert(<span class="hljs-string">'see'</span>);

<span class="hljs-built_in">console</span>.log(t.search(<span class="hljs-string">'sea'</span>)); <span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(t.search(<span class="hljs-string">'see'</span>)); <span class="hljs-comment">// true</span>

<span class="hljs-built_in">console</span>.log(t.search(<span class="hljs-string">'hey'</span>)); <span class="hljs-comment">// false</span>
<span class="hljs-built_in">console</span>.log(t.search(<span class="hljs-string">'sew'</span>)); <span class="hljs-comment">// false</span>

t.remove(<span class="hljs-string">'see'</span>);

<span class="hljs-built_in">console</span>.log(t.search(<span class="hljs-string">'see'</span>)); <span class="hljs-comment">// false </span>
<span class="hljs-built_in">console</span>.log(t.search(<span class="hljs-string">'sea'</span>)); <span class="hljs-comment">// true</span>
</code></pre>
<h4 id="heading-time-and-space-complexity-12">Time and space complexity</h4>
<p>The time complexity of creating a trie is going to be \(O(m * n)\) where \(m\) is the longest word and \(n\) is the total number of words. Inserting, searching, and deleting a word is \(O(a * n)\) where \(a\) is the length of the word and \(n\) is the total number of words.</p>
<p>When it comes to space complexity, in the worst case, each node can have children for all the characters in the alphabet we're representing. But, the size of the alphabet is constant, so the growth of storage needs will be proportionate to the number of nodes we have, which is \(O(n)\) where \(n\) is the number of nodes.</p>
<h2 id="heading-chapter-eleven-graphs">Chapter Eleven: Graphs</h2>
<p>A graph is probably <em>the</em> data structure that everyone is familiar with, regardless of their profession or interests.</p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Graph_theory#Representation">Graph theory</a> is a very broad topic, but we'll simply look at some of the main ingredients of what makes a graph and how to represent it, as well as basic graph traversals.</p>
<p>In a graph, there are two main components: vertices (or nodes) and edges that connect those vertices.</p>
<p><strong>Note:</strong> Here, we're going to use "vertex" and "node" interchangeably. The terms "adjacent vertices" and "neighbors" are used interchangeably as well.</p>
<p>A graph can be <strong>directed</strong> or <strong>undirected</strong>. With a directed edge, we have an origin and a destination vertex. On the other hand, an undirected edge is bidirectional, origin and destination are not fixed.</p>
<p><strong>Note:</strong> There might also be <a target="_blank" href="https://en.wikipedia.org/wiki/Graph_\(discrete_mathematics\)#Mixed_graph">mixed graphs</a> that have both directed and undirected edges.</p>
<p>A graph can also be weighted or unweighted, each edge can have different weights, usually representing the cost of going from one vertex to the other.</p>
<p>We can define a graph like this:</p>
<p>$$G = (V, \ E)$$</p><p>\(V\) is a set of vertices, and \(E\) is a set of edges.</p>
<p>For example, if we have a directed graph like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747921387268/fe3d0ef9-a271-4c87-9143-84e80e41af5f.gif" alt="Animated visualization of a graph with nodes A, B, C, D. A has directed edges to B and C, C has one to B and D. D has one to C. " class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>Then, we have the vertices:</p>
<p>$$V = \{A, \ B, \ C, \ D\}$$</p><p>And, the edges are:</p>
<p>$$E = \{(A, \ B), \ (A, \ C), \ (C, \ B), \ (C, \ D)\, \ (D, \ C)\}$$</p><p>If we have an undirected graph such as this one:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747921458245/d2920859-81c0-4082-a49d-e41b08b81124.gif" alt="Animated visualization of the same graph above with undirected edges." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>We have the same vertices:</p>
<p>$$V = \{A, \ B, \ C, \ D\}$$</p><p>But our edges can look like this:</p>
<p>$$E = \{\{B, \ A\}, \{A, \ C\}, \{C, \ B\}, \{D, \ C\}\}$$</p><p><strong>Note:</strong> We use parentheses when it comes to directed edges, but curly braces with undirected edges as there is no direction from one vertex to the other.</p>
<p>When two vertices share an edge, they are <strong>adjacent</strong> to each other. The <strong>degree</strong> of a vertex is the number of adjacent vertices to it. We can also define the degree as the number of edges coming out of the vertex. For example, in the above image, the vertex A has a degree of 2.</p>
<p>A <strong>simple path</strong> is the one that we don't repeat any vertices while traversing the graph.</p>
<p>An example might look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747921569022/50f556e7-f954-4203-8c4b-493b2be5a353.gif" alt="Animated visualization of the same graph above with highlighted nodes in this order: A, B, C, D." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>A <strong>cycle</strong> is a simple path, except that we end up at the vertex we started with:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747921594728/717408ba-f9fb-4cef-9b52-70f487e9162d.gif" alt="Animated visualization of the same graph above with highlighted nodes in this order: A, B, C (with all the edges also highlighted)." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<h3 id="heading-representing-graphs">Representing graphs</h3>
<p>When it comes to representing graphs, there are several ways to do it, and we'll look at three of them: an edge list, an adjacency matrix, and an adjacency list.</p>
<h4 id="heading-edge-list">Edge List</h4>
<p>We can simply put all the edges in an array:</p>
<pre><code class="lang-plaintext">[ [A, B], [A, C], [B, C], [C, D] ]
</code></pre>
<p>But to find an edge in an edge list, we'll have to iterate through them, so it will have \(O(E)\) time complexity, where in the worst case, we'll search the whole list to find an edge. Similarly, it needs \(O(E)\) amount of space to represent all the edges.</p>
<h4 id="heading-adjacency-matrix">Adjacency Matrix</h4>
<p>The adjacency matrix for our example might look like this:</p>
<p>$$\left\lceil\begin{matrix}&amp; A &amp; B &amp; C &amp; D \\A &amp; 0 &amp; 1 &amp; 1 &amp; 0 \\B &amp; 1 &amp; 0 &amp; 1 &amp; 0 \\C &amp; 1 &amp; 1 &amp; 0 &amp; 1 \\D &amp; 0 &amp; 0 &amp; 1 &amp; 0\end{matrix}\right\rceil$$</p><p>Each row is for a vertex, and the matching column shows the relationship between those vertices. For example, the vertex A doesn't have an edge pointing to D, so the cell that matches A and D is 0. On the other hand, A is connected to B and C, so those cells have the value 1.</p>
<p><strong>Note:</strong> If the graph is weighted, we can simply put the weight instead of <code>1</code>, and when there is no edge, the value can stay <code>0</code>.</p>
<p><em>An adjacency matrix will have 0s in the "main diagonal," showing that there are no self-loops.</em></p>
<p>Let's try implementing it in TypeScript.</p>
<p>We'll start with a minimal graph vertex:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> GraphVertex {
  value: <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">value: <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">this</span>.value = value;
  }
}
</code></pre>
<p>Now we can define our graph. We'll make it really simple with three properties to hold: <code>matrix</code> to represent the graph as an adjacency matrix, <code>vertices</code> to hold vertices, and <code>isDirected</code> to indicate whether our graph is directed:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Graph {
  matrix: <span class="hljs-built_in">number</span>[][];
  vertices: GraphVertex[];
  isDirected: <span class="hljs-built_in">boolean</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">vertices: GraphVertex[], isDirected = <span class="hljs-literal">true</span></span>) {
    <span class="hljs-built_in">this</span>.vertices = vertices;
    <span class="hljs-built_in">this</span>.isDirected = isDirected;
    <span class="hljs-comment">// ...</span>
  }

  <span class="hljs-comment">// ...</span>
}
</code></pre>
<p>Initializing our adjacency matrix might look like this:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">this</span>.matrix = <span class="hljs-built_in">Array</span>.from({ length: vertices.length }, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">Array</span>.from({ length: vertices.length }, <span class="hljs-function">() =&gt;</span> <span class="hljs-number">0</span>)
});
</code></pre>
<p>We'll have an array with the length of vertices. Each item in the array is an array with the length of vertices as well, but filled with zeroes.</p>
<p>In our example with four vertices, the initial adjacency matrix looks like this:</p>
<pre><code class="lang-typescript">[ [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>], [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>], [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>], [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>] ]
</code></pre>
<p>Then, adding an edge is just marking the corresponding value as <code>1</code>, so that we can represent a connection between two vertices:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">this</span>.matrix[<span class="hljs-built_in">this</span>.vertices.indexOf(v1)][<span class="hljs-built_in">this</span>.vertices.indexOf(v2)] = <span class="hljs-number">1</span>;
</code></pre>
<p><strong>Note:</strong> This implementation assumes that all vertices are distinct.</p>
<p>If we have an undirected graph, we can have it both ways:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isDirected) {
  <span class="hljs-built_in">this</span>.matrix[<span class="hljs-built_in">this</span>.vertices.indexOf(v2)][<span class="hljs-built_in">this</span>.vertices.indexOf(v1)] = <span class="hljs-number">1</span>;
}
</code></pre>
<p>Removing an edge, in this case, will be just resetting the value to <code>0</code>:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">this</span>.matrix[<span class="hljs-built_in">this</span>.vertices.indexOf(v1)][<span class="hljs-built_in">this</span>.vertices.indexOf(v2)] = <span class="hljs-number">0</span>;
</code></pre>
<p>And, checking for the existence of an edge is simply checking whether the corresponding value is <code>0</code> or not:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">this</span>.matrix[<span class="hljs-built_in">this</span>.vertices.indexOf(v1)][<span class="hljs-built_in">this</span>.vertices.indexOf(v2)] !== <span class="hljs-number">0</span>;
</code></pre>
<p>And, here is the whole example with additional methods for adding and removing an edge, checking if there is an edge between two vertices, and checking if a specific vertex is in the graph:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Graph {
  matrix: <span class="hljs-built_in">number</span>[][];
  vertices: GraphVertex[];
  isDirected: <span class="hljs-built_in">boolean</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">vertices: GraphVertex[], isDirected = <span class="hljs-literal">true</span></span>) {
    <span class="hljs-built_in">this</span>.vertices = vertices;
    <span class="hljs-built_in">this</span>.matrix = <span class="hljs-built_in">Array</span>.from({ length: vertices.length }, <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">Array</span>.from({ length: vertices.length }, <span class="hljs-function">() =&gt;</span> <span class="hljs-number">0</span>)
    });
    <span class="hljs-built_in">this</span>.isDirected = isDirected;
  }

  addEdge(v1: GraphVertex, v2: GraphVertex) {
    <span class="hljs-built_in">this</span>._checkVertexIsInGraph(v1);
    <span class="hljs-built_in">this</span>._checkVertexIsInGraph(v2);

    <span class="hljs-built_in">this</span>.matrix[<span class="hljs-built_in">this</span>.vertices.indexOf(v1)][<span class="hljs-built_in">this</span>.vertices.indexOf(v2)] = <span class="hljs-number">1</span>;

    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isDirected) {
      <span class="hljs-built_in">this</span>.matrix[<span class="hljs-built_in">this</span>.vertices.indexOf(v2)][<span class="hljs-built_in">this</span>.vertices.indexOf(v1)] = <span class="hljs-number">1</span>;
    }
  }

  <span class="hljs-comment">/* 
  For a weighted graph:

  addEdge(v1: GraphVertex, v2: GraphVertex, weight: number) {
    this._checkVertexIsInGraph(v1);
    this._checkVertexIsInGraph(v2);

    this.matrix[this.vertices.indexOf(v1)][this.vertices.indexOf(v2)] = weight;
    if (!this.isDirected) {
      this.matrix[this.vertices.indexOf(v2)][this.vertices.indexOf(v1)] = weight;
    }
  }
  */</span>

  removeEdge(v1: GraphVertex, v2: GraphVertex) {
    <span class="hljs-built_in">this</span>._checkVertexIsInGraph(v1);
    <span class="hljs-built_in">this</span>._checkVertexIsInGraph(v2);

    <span class="hljs-built_in">this</span>.matrix[<span class="hljs-built_in">this</span>.vertices.indexOf(v1)][<span class="hljs-built_in">this</span>.vertices.indexOf(v2)] = <span class="hljs-number">0</span>;

    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isDirected) {
      <span class="hljs-built_in">this</span>.matrix[<span class="hljs-built_in">this</span>.vertices.indexOf(v2)][<span class="hljs-built_in">this</span>.vertices.indexOf(v1)] = <span class="hljs-number">0</span>;
    }
  }

  hasEdge(v1: GraphVertex, v2: GraphVertex) {
    <span class="hljs-built_in">this</span>._checkVertexIsInGraph(v1);
    <span class="hljs-built_in">this</span>._checkVertexIsInGraph(v2);

    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.matrix[<span class="hljs-built_in">this</span>.vertices.indexOf(v1)][<span class="hljs-built_in">this</span>.vertices.indexOf(v2)] !== <span class="hljs-number">0</span>;
  }

  getAdjacencyMatrix() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.matrix;
  }

  _checkVertexIsInGraph(v: GraphVertex) {
    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.vertices.includes(v)) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Vertex doesn\'t exist'</span>);
    }
  }
}


<span class="hljs-keyword">let</span> a = <span class="hljs-keyword">new</span> GraphVertex(<span class="hljs-string">'A'</span>);
<span class="hljs-keyword">let</span> b = <span class="hljs-keyword">new</span> GraphVertex(<span class="hljs-string">'B'</span>);
<span class="hljs-keyword">let</span> c = <span class="hljs-keyword">new</span> GraphVertex(<span class="hljs-string">'C'</span>);
<span class="hljs-keyword">let</span> d = <span class="hljs-keyword">new</span> GraphVertex(<span class="hljs-string">'D'</span>);

<span class="hljs-keyword">let</span> graph = <span class="hljs-keyword">new</span> Graph([a, b, c, d], <span class="hljs-literal">false</span>);

graph.addEdge(a, b);
graph.addEdge(a, c);
graph.addEdge(b, c);
graph.addEdge(c, d);

<span class="hljs-built_in">console</span>.log(graph.getAdjacencyMatrix());
<span class="hljs-comment">// -&gt; [ [0, 1, 1, 0], [1, 0, 1, 0], [1, 1, 0, 1], [0, 0, 1, 0] ]</span>
</code></pre>
<p>Operations on an adjacency matrix have \(O(1)\) time complexity. But our storage needs will be \(O(V^2)\) where \(V\) is the number of vertices.</p>
<h4 id="heading-adjacency-list">Adjacency List</h4>
<p>In an adjacency list, usually a hashmap <strong>or</strong> an array of linked lists is used. For example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> graph = {
  <span class="hljs-string">'A'</span>: [<span class="hljs-string">'B'</span>, <span class="hljs-string">'C'</span>],
  <span class="hljs-string">'B'</span>: [<span class="hljs-string">'A'</span>, <span class="hljs-string">'C'</span>],
  <span class="hljs-string">'C'</span>: [<span class="hljs-string">'A'</span>, <span class="hljs-string">'B'</span>, <span class="hljs-string">'D'</span>],
  <span class="hljs-string">'D'</span>: [<span class="hljs-string">'C'</span>]
}
</code></pre>
<p>Let's see how we can modify our code above to use an adjacency list instead.</p>
<p>Instead of having a <code>matrix</code> which is an array of arrays, we can have a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map"><code>Map</code></a> that maps the vertices to an array of their neighbors.</p>
<p>We can initialize it as a map that has the vertices as keys, each of which has a value of an empty array for now:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">this</span>.list = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>&lt;GraphVertex, GraphVertex[]&gt;();
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> v <span class="hljs-keyword">of</span> vertices) {
  <span class="hljs-built_in">this</span>.list.set(v, []);
}
</code></pre>
<p>Adding an edge will be just pushing to the array of corresponding vertex:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">this</span>.list.get(v1)!.push(v2);
</code></pre>
<p>If our graph is undirected, we can do it both ways here as well:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isDirected) {
  <span class="hljs-built_in">this</span>.list.get(v2)!.push(v1);
}
</code></pre>
<p>Removing an edge will be deleting that vertex from the array:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">this</span>.list.set(v1, <span class="hljs-built_in">this</span>.list.get(v1)!.filter(<span class="hljs-function"><span class="hljs-params">v</span> =&gt;</span> v !== v2));
</code></pre>
<p>Checking if an edge exists is just checking the existence of that vertex in the array:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">this</span>.list.get(v1)!.includes(v2);
</code></pre>
<p><strong>Note:</strong> We're using a <a target="_blank" href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator">non-null assertion operator</a> as we’re using TypeScript in these examples. As we'll see below, we first check if the vertex is in the graph. And since we're adding all the vertices in the graph as keys to <code>this.list</code>, we're sure that getting that vertex from the list is not <code>undefined</code>. But TypeScript will warn us because if a key is not found in a <code>Map</code> object, it could <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get#return_value">potentially return <code>undefined</code></a>.</p>
<p>Here is our graph:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Graph {
  list: <span class="hljs-built_in">Map</span>&lt;GraphVertex, GraphVertex[]&gt;;
  vertices: GraphVertex[];
  isDirected: <span class="hljs-built_in">boolean</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">vertices: GraphVertex[], isDirected = <span class="hljs-literal">true</span></span>) {
    <span class="hljs-built_in">this</span>.vertices = vertices;
    <span class="hljs-built_in">this</span>.list = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> v <span class="hljs-keyword">of</span> vertices) {
      <span class="hljs-built_in">this</span>.list.set(v, []);
    }
    <span class="hljs-built_in">this</span>.isDirected = isDirected;
  }

  addEdge(v1: GraphVertex, v2: GraphVertex) {
    <span class="hljs-built_in">this</span>._checkVertexIsInGraph(v1);
    <span class="hljs-built_in">this</span>._checkVertexIsInGraph(v2);

    <span class="hljs-built_in">this</span>.list.get(v1)!.push(v2);

    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isDirected) {
      <span class="hljs-built_in">this</span>.list.get(v2)!.push(v1);
    }
  }

  removeEdge(v1: GraphVertex, v2: GraphVertex) {
    <span class="hljs-built_in">this</span>._checkVertexIsInGraph(v1);
    <span class="hljs-built_in">this</span>._checkVertexIsInGraph(v2);

    <span class="hljs-built_in">this</span>.list.set(v1, <span class="hljs-built_in">this</span>.list.get(v1)!.filter(<span class="hljs-function"><span class="hljs-params">v</span> =&gt;</span> v !== v2));

    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isDirected) {
      <span class="hljs-built_in">this</span>.list.set(v2, <span class="hljs-built_in">this</span>.list.get(v2)!.filter(<span class="hljs-function"><span class="hljs-params">v</span> =&gt;</span> v !== v1));
    }
  }

  hasEdge(v1: GraphVertex, v2: GraphVertex) {
    <span class="hljs-built_in">this</span>._checkVertexIsInGraph(v1);
    <span class="hljs-built_in">this</span>._checkVertexIsInGraph(v2);

    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.list.get(v1)!.includes(v2);
  }

  getAdjacencyList() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.list;
  }

  _checkVertexIsInGraph(v: GraphVertex) {
    <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.vertices.includes(v)) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Vertex doesn\'t exist'</span>);
    }
  }
}


<span class="hljs-keyword">let</span> a = <span class="hljs-keyword">new</span> GraphVertex(<span class="hljs-string">'A'</span>);
<span class="hljs-keyword">let</span> b = <span class="hljs-keyword">new</span> GraphVertex(<span class="hljs-string">'B'</span>);
<span class="hljs-keyword">let</span> c = <span class="hljs-keyword">new</span> GraphVertex(<span class="hljs-string">'C'</span>);
<span class="hljs-keyword">let</span> d = <span class="hljs-keyword">new</span> GraphVertex(<span class="hljs-string">'D'</span>);

<span class="hljs-keyword">let</span> graph = <span class="hljs-keyword">new</span> Graph([a, b, c, d], <span class="hljs-literal">false</span>);

graph.addEdge(a, b);
graph.addEdge(a, c);
graph.addEdge(b, c);
graph.addEdge(c, d);

<span class="hljs-built_in">console</span>.log(graph.getAdjacencyList());

<span class="hljs-comment">/* Output:

Map (4) {
  GraphVertex: { "value": "A" } =&gt; [
    GraphVertex: { "value": "B" }, 
    GraphVertex: { "value": "C" }
  ], 
  GraphVertex: { "value": "B" } =&gt; [
    GraphVertex: { "value": "A" }, 
    GraphVertex: { "value": "C" }
  ], 
  GraphVertex: { "value": "C" } =&gt; [
    GraphVertex: { "value": "A" }, 
    GraphVertex: { "value": "B" }, 
    GraphVertex: { "value": "D" }
  ], 
  GraphVertex: { "value": "D" } =&gt; [
    GraphVertex: { "value": "C" }
  ]
} 

*/</span>
</code></pre>
<p>Getting the neighbors of a vertex is \(O(1)\) because we're just looking up a key in a map. But finding a particular edge can be \(O(d)\) where \(d\) is the number of degrees of the vertex, because we might need to traverse all the neighbors to find it. And, it could be \(V - 1\) where \(V\) is the number of vertices in the graph. It's the case when that vertex has all the other vertices as its neighbors.</p>
<p>The space complexity can be \(O(V + E)\) where \(V\) is the number of vertices and \(E\) is the number of edges.</p>
<h3 id="heading-traversals-1">Traversals</h3>
<p>Continuing with the adjacency list representation, let's now take a look at two (very familiar) ways to traverse a graph: breadth-first search and depth-first search.</p>
<p>But first, we'll modify our graph a little bit. We'll add a new vertex <code>'E'</code> and update some edges:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> a = <span class="hljs-keyword">new</span> GraphVertex(<span class="hljs-string">'A'</span>);
<span class="hljs-keyword">let</span> b = <span class="hljs-keyword">new</span> GraphVertex(<span class="hljs-string">'B'</span>);
<span class="hljs-keyword">let</span> c = <span class="hljs-keyword">new</span> GraphVertex(<span class="hljs-string">'C'</span>);
<span class="hljs-keyword">let</span> d = <span class="hljs-keyword">new</span> GraphVertex(<span class="hljs-string">'D'</span>);
<span class="hljs-keyword">let</span> e = <span class="hljs-keyword">new</span> GraphVertex(<span class="hljs-string">'E'</span>);


<span class="hljs-keyword">let</span> graph = <span class="hljs-keyword">new</span> Graph([a, b, c, d, e], <span class="hljs-literal">false</span>);

graph.addEdge(a, b);
graph.addEdge(a, c);
graph.addEdge(b, d);
graph.addEdge(c, e);
</code></pre>
<p>The important idea to remember is that there is no hierarchy of vertices, so we don't have a root node.</p>
<p>For a breadth-first or depth-first search, we can use an arbitrary node as a starting point.</p>
<h4 id="heading-breadth-first-search">Breadth-First Search</h4>
<p>With our new graph, a breadth-first search traversal looks like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747922399341/f4b9f63b-5188-48a2-83ec-51524721c2b1.gif" alt="Animated visualization for a breadth-first search of a graph with nodes A, B, C, D, E with highlighted nodes in this order: A, B, C, D, E." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>When it comes to breadth-first search, usually a queue is used, and the idea is simple: given a current node, we'll add the adjacent nodes first, marking them as visited as we go.</p>
<p>Inside the <code>Graph</code> class, we can implement a <code>bfs</code> method that does just that:</p>
<pre><code class="lang-typescript">bfs(startNode: GraphVertex) {
  <span class="hljs-keyword">const</span> visited = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>();
  <span class="hljs-keyword">const</span> queue = [startNode];
  visited.add(startNode);

  <span class="hljs-keyword">while</span> (queue.length &gt; <span class="hljs-number">0</span>) {
    <span class="hljs-keyword">const</span> currentNode = queue.shift();
    <span class="hljs-comment">// console.log(currentNode);</span>
    <span class="hljs-built_in">this</span>.list.get(currentNode <span class="hljs-keyword">as</span> GraphVertex)!.forEach(<span class="hljs-function">(<span class="hljs-params">node</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (!visited.has(node)) {
        visited.add(node);
        queue.push(node);
      }
    });
  }
}
</code></pre>
<p>If we call the <code>bfs</code> method with <code>a</code> as the starting vertex (<code>graph.bfs(a)</code>), and log <code>currentNode</code> to console each time we go, it's as we expected:</p>
<pre><code class="lang-plaintext">GraphVertex { value: 'A' }
GraphVertex { value: 'B' }
GraphVertex { value: 'C' }
GraphVertex { value: 'D' }
GraphVertex { value: 'E' }
</code></pre>
<p>With the adjacency list, using a BFS has \(O(V + E)\) time complexity (sum of the vertices and edges) as we're traversing the whole graph.</p>
<h4 id="heading-depth-first-search">Depth-First Search</h4>
<p>With the same modified graph, a depth-first search looks like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747922463260/72e852c1-642f-4ce0-829d-e658a8a7b880.gif" alt="Animated visualization for a depth-first search of a graph with nodes A, B, C, D, E with highlighted nodes in this order: A, B, D, C, E." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>With depth-first search there is usually recursion involved as we're traversing through a path until we have visited all the nodes in that path. Once we hit a dead end, we'll <strong>backtrack</strong> and continue exploring until we have visited all the vertices in the graph.</p>
<p>Again, inside the <code>Graph</code> class, we can add a <code>dfs</code> method:</p>
<pre><code class="lang-typescript">dfs(startNode: GraphVertex, visited = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>()) {
  visited.add(startNode);
  <span class="hljs-comment">// console.log(startNode);</span>
  <span class="hljs-built_in">this</span>.list.get(startNode)!.forEach(<span class="hljs-function">(<span class="hljs-params">node</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (!visited.has(node)) {
      <span class="hljs-built_in">this</span>.dfs(node, visited);
    }
  });
}
</code></pre>
<p>Starting with a node, we check how deep we can go from there. Once we reach a dead end (when the <code>dfs</code> inside <code>forEach</code> returns), we continue checking other neighbors (with <code>forEach</code>) until none is left. We essentially do the same thing until all the vertices are visited.</p>
<p>Logging the output matches our expectation:</p>
<pre><code class="lang-plaintext">GraphVertex { value: 'A' }
GraphVertex { value: 'B' }
GraphVertex { value: 'D' }
GraphVertex { value: 'C' }
GraphVertex { value: 'E' }
</code></pre>
<p>The time complexity for a depth-first search traversal of a graph is the similar to BFS, \(O(V + E)\).</p>
<h2 id="heading-chapter-twelve-dynamic-programming">Chapter Twelve: Dynamic Programming</h2>
<p>Dynamic programming (DP) is one of those concepts that is a bit intimidating when you hear it for the first time. But the crux of it is simply breaking problems down into smaller parts and solving them. It’s also about storing those solutions so that we don't have to compute them again.</p>
<p>Breaking problems down into subproblems is nothing new – that's pretty much what problem-solving is all about. What dynamic programming is also specifically concerned with are <strong>overlapping subproblems</strong> that are repeating – we want to calculate solutions to those subproblems so that we won't be calculating them again each time. Put another way, <em>we want to remember the past so that we won't be condemned to repeat it</em>.</p>
<p>For example, calculating 1 + 1 + 1 + 1 + 1 is very easy if we have already calculated 1 + 1 + 1 + 1. We can just remember the previous solution, and use it:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747922611072/bcb33cae-aed3-41bd-8823-4e10a0e13fbf.gif" alt="Animated visualization of the result of 1 + 1 + 1 + 1 constituting a subproblem of 1 + 1 + 1 + 1 + 1 ." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>Calculating the Fibonacci sequence is one of the well-known examples when it comes to dynamic programming. Because we have to calculate the same functions each time for a new number, it lends itself to DP very well.</p>
<p>For example, to calculate <code>fib(4)</code> we need to calculate <code>fib(3)</code> and <code>fib(2)</code>. But calculating <code>fib(3)</code> also involves calculating <code>fib(2)</code>, so we'll be doing the same calculation, <em>again</em>.</p>
<p>A classic, good old recursive Fibonacci function might look like this:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fib</span>(<span class="hljs-params">n: <span class="hljs-built_in">number</span></span>): <span class="hljs-title">number</span> </span>{
  <span class="hljs-keyword">if</span> (n === <span class="hljs-number">0</span> || n === <span class="hljs-number">1</span>) {
    <span class="hljs-keyword">return</span> n;
  }

  <span class="hljs-keyword">return</span> fib(n - <span class="hljs-number">1</span>) + fib(n - <span class="hljs-number">2</span>);
}
</code></pre>
<p>Though the issue we have just mentioned remains: we'll keep calculating the same values:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747922659848/577aef57-17b5-40ad-a926-74387b0e3731.gif" alt="Animated visualization displaying repeated fibonacci calls." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>But, we want to do better.</p>
<p><strong>Memoization</strong> is remembering the problems we have solved before so that we don't have to solve them again and waste our time. We can <em>reuse</em> the solution to the subproblem we've already memoized. So, we can keep a <em>cache</em> to store those solutions and use them:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fib</span>(<span class="hljs-params">n: <span class="hljs-built_in">number</span>, cache: <span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">number</span>, <span class="hljs-built_in">number</span>&gt;</span>): <span class="hljs-title">number</span> </span>{
  <span class="hljs-keyword">if</span> (cache.has(n)) {
    <span class="hljs-keyword">return</span> cache.get(n)!;
  }

  <span class="hljs-keyword">if</span> (n === <span class="hljs-number">0</span> || n === <span class="hljs-number">1</span>) {
    <span class="hljs-keyword">return</span> n;
  }

  <span class="hljs-keyword">const</span> result = fib(n - <span class="hljs-number">1</span>, cache) + fib(n - <span class="hljs-number">2</span>, cache);
  cache.set(n, result);

  <span class="hljs-keyword">return</span> result;
}
</code></pre>
<p>For example, we can initially pass an empty <code>Map</code> as the argument for <code>cache</code>, and print the first 15 Fibonacci numbers:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> m = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>&lt;<span class="hljs-built_in">number</span>, <span class="hljs-built_in">number</span>&gt;();

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">15</span>; i++) {
  <span class="hljs-built_in">console</span>.log(fib(i, m));
}

<span class="hljs-comment">/*
  0
  1
  1
  2
  3
  5
  8
  13
  21
  34
  55 
  89
  144
  233
  377 
 */</span>
</code></pre>
<p>There are two different approaches with dynamic programming: <strong>top-down</strong> and <strong>bottom-up</strong>.</p>
<p>Top-down is like what it sounds: starting with a large problem, breaking it down to smaller components, memoizing them. It's what we just did with the <code>fib</code> example.</p>
<p>Bottom-up is also like what it sounds: starting with the smallest subproblem, finding out a solution, and working our way up to the larger problem itself. It also has an advantage: with the bottom-up approach, we don't need to store every previous value – we can only keep the two elements at the bottom so that we can use them to build up to our target.</p>
<p>With the bottom-up approach, our <code>fib</code> function can look like this:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fib</span>(<span class="hljs-params">n: <span class="hljs-built_in">number</span></span>) </span>{
  <span class="hljs-keyword">let</span> dp = [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>];
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">2</span>; i &lt;= n; i++) {
    dp[i] = dp[i - <span class="hljs-number">1</span>] + dp[i - <span class="hljs-number">2</span>];
  }

  <span class="hljs-keyword">return</span> dp[n];
}
</code></pre>
<p>Just note that we are keeping an array whose size will grow linearly as the input increases. So, we can do better with constant space complexity, not using an array at all:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fib</span>(<span class="hljs-params">n: <span class="hljs-built_in">number</span></span>) </span>{
  <span class="hljs-keyword">if</span> (n === <span class="hljs-number">0</span> || n === <span class="hljs-number">1</span>) {
    <span class="hljs-keyword">return</span> n;
  }

  <span class="hljs-keyword">let</span> a = <span class="hljs-number">0</span>;
  <span class="hljs-keyword">let</span> b = <span class="hljs-number">1</span>;

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">2</span>; i &lt;= n; i++) {
    <span class="hljs-keyword">let</span> tmp = a + b;
    a = b;
    b = tmp;
  }

  <span class="hljs-keyword">return</span> b;
}
</code></pre>
<h4 id="heading-time-and-space-complexity-13">Time and space complexity</h4>
<p>The time complexities for both the top-down and bottom-up approaches in the Fibonacci example are \(O(n)\) as we solve each subproblem, each of which is of constant time.</p>
<p><strong>Note:</strong> The time complexity of the recursive Fibonacci function that doesn't use DP is exponential (in fact, \(O(\phi^{n})\) – yes <a target="_blank" href="https://en.wikipedia.org/wiki/Golden_ratio">the golden ratio</a> as its base).</p>
<p>But when it comes to space complexity, the bottom-up approach (the second version) is \(O(1)\).</p>
<p><strong>Note:</strong> The first version we've used for the bottom-up approach has \(O(n)\) time complexity as we store the values in an array.</p>
<p>The top-down approach has \(O(n)\) space complexity because we store a <code>Map</code> whose size will grow linearly as <code>n</code> increases.</p>
<h2 id="heading-chapter-thirteen-intervals">Chapter Thirteen: Intervals</h2>
<p>An interval simply has a start and an end. The easiest way to think about intervals is as time frames.</p>
<p>With intervals, the usual concern is whether they overlap or not.</p>
<p>For example, if we have an interval <code>[1, 3]</code> and another <code>[2, 5]</code>, they are clearly overlapping, so they can be merged together to create a new interval <code>[1, 5]</code>:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747923034510/05767713-f24f-4467-82f5-89e025631be9.gif" alt="Animated visualization with interval [1, 3] merging with [2, 5], becoming [1, 5]." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<p>In order for two intervals <strong>not to overlap</strong>:</p>
<ul>
<li>the <em>start</em> of one should be <em>strictly larger</em> than the <em>end</em> of the other</li>
</ul>
<pre><code class="lang-plaintext">newInterval[0] &gt; interval[1]
</code></pre>
<p>Or:</p>
<ul>
<li>the <em>end</em> of the one should be <em>strictly smaller</em> than the <em>start</em> of the other</li>
</ul>
<pre><code class="lang-plaintext">newInterval[1] &lt; interval[0]
</code></pre>
<p>If both of these are false, they are overlapping.</p>
<p>If they are overlapping, the new (merged) interval will have the minimum value from both intervals as its start, and the maximum as its end:</p>
<pre><code class="lang-plaintext">[
  min(newInterval[0], interval[0]),
  max(newInterval[1], interval[1])
]
</code></pre>
<h2 id="heading-chapter-fourteen-bit-manipulation">Chapter Fourteen: Bit Manipulation</h2>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Bitwise_operation">A bitwise operation</a> operates on a bit string, a bit array, or a binary numeral (considered as a bit string) at the level of its individual bits.</p>
<p>Let's first represent a number in binary (base 2). We can use <code>toString</code> method on a <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number">number</a>, and specify the <strong>radix</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> n = <span class="hljs-number">17</span>;

<span class="hljs-built_in">console</span>.log(n.toString(<span class="hljs-number">2</span>)); <span class="hljs-comment">// 10001</span>
</code></pre>
<p>We can also parse an integer giving it a base:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">parseInt</span>(<span class="hljs-number">10001</span>, <span class="hljs-number">2</span>)); <span class="hljs-comment">// 17</span>
</code></pre>
<p><strong>Note:</strong> We can also represent a binary number with the prefix <code>0b</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-number">0b10001</span>); <span class="hljs-comment">// 17</span>
<span class="hljs-built_in">console</span>.log(<span class="hljs-number">0b101</span>); <span class="hljs-comment">// 5</span>
</code></pre>
<p>For example, these are the same number:</p>
<pre><code class="lang-javascript"><span class="hljs-number">0b1</span> === <span class="hljs-number">0b00000001</span> <span class="hljs-comment">// true</span>
</code></pre>
<p>All bitwise operations are performed on 32-bit binary numbers in JavaScript. That is, <em>before a bitwise operation is performed, JavaScript converts numbers to 32-bit</em> <strong><em>signed</em></strong> <em>integers.</em></p>
<p>So, for example, <code>17</code> won't be simply <code>10001</code> but <code>00000000 00000000 00000000 00010001</code>.</p>
<p><em>After the bitwise operation is performed, the result is converted back to 64-bit JavaScript numbers.</em></p>
<h3 id="heading-bitwise-operators">Bitwise operators</h3>
<h4 id="heading-and-amp">AND (<code>&amp;</code>)</h4>
<p>If two bits are <code>1</code>, the result is <code>1</code>, otherwise <code>0</code>.</p>
<p>The GIFs below show the numbers as 8-bit strings, but when doing bitwise operations, remember they are converted to 32-bit numbers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747923324409/4415a01f-6129-4dcf-a1ce-b8e898bdba9a.gif" alt="Animated visualization of an AND operation. 00010001 &amp; 00000101 = 00000001." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> x1 = <span class="hljs-number">0b10001</span>;
<span class="hljs-keyword">const</span> x2 = <span class="hljs-number">0b101</span>;

<span class="hljs-keyword">const</span> result = x1 &amp; x2; <span class="hljs-comment">// 1 (0b1)</span>
</code></pre>
<h4 id="heading-or">OR (<code>|</code>)</h4>
<p>If either of the bits is <code>1</code>, the result is <code>1</code>, otherwise <code>0</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747923365941/22e562c4-e195-4567-b8ef-4b94cb4a394f.gif" alt="Animated visualization of an OR operation. 00010001 | 00000101 = 00010101." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> x1 = <span class="hljs-number">0b10001</span>;
<span class="hljs-keyword">const</span> x2 = <span class="hljs-number">0b101</span>;

<span class="hljs-keyword">const</span> result = x1 | x2; <span class="hljs-comment">// 21 (0b10101)</span>
</code></pre>
<h4 id="heading-xor">XOR (<code>^</code>)</h4>
<p>If the bits are different (one is <code>1</code> and the other is <code>0</code>), the result is <code>1</code>, otherwise <code>0</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747923403151/52090e1a-98ee-4303-a433-6318ec6f18d2.gif" alt="Animated visualization of a XOR operation. 00010001 ^ 00000101 = 00010100." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> x1 = <span class="hljs-number">0b10001</span>;
<span class="hljs-keyword">const</span> x2 = <span class="hljs-number">0b101</span>;

<span class="hljs-keyword">const</span> result = x1 ^ x2; <span class="hljs-comment">// 20 (0b10100)</span>
</code></pre>
<h4 id="heading-not">NOT (<code>~</code>)</h4>
<p>Flips the bits (<code>1</code> becomes <code>0</code>, <code>0</code> becomes <code>1</code>).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1747923458432/2807b821-8069-45e6-a37b-d8167ec722e7.gif" alt="Animated visualization of a NOT operation. ~00010001 = 11101110." class="image--center mx-auto" width="1080" height="608" loading="lazy"></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> n = <span class="hljs-number">17</span>;

<span class="hljs-keyword">const</span> result = ~n; <span class="hljs-comment">// -18</span>
</code></pre>
<p><strong>Note:</strong> Bitwise NOTing any 32-bit integer <code>x</code> yields <code>-(x + 1)</code>.</p>
<p>If we use <a target="_blank" href="https://stackoverflow.com/a/33758875">a helper function</a> to see the binary representations, it is as we expected:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(createBinaryString(n));
<span class="hljs-comment">// -&gt; 00000000 00000000 00000000 00010001</span>

<span class="hljs-built_in">console</span>.log(createBinaryString(result));
<span class="hljs-comment">// -&gt; 11111111 11111111 11111111 11101110</span>
</code></pre>
<p>The leftmost bit indicates the signal – whether the number is negative or positive.</p>
<p>Remember that we said JavaScript uses 32-bit <strong>signed</strong> integers for bitwise operations. <strong>The leftmost bit is</strong> <code>1</code> for negative numbers and <code>0</code> for positive numbers. Also, the operator operates on the operands' bit representations in <a target="_blank" href="https://en.wikipedia.org/wiki/Two's_complement">two's complement</a>. The operator is applied to each bit, and the result is constructed bitwise.</p>
<p><strong>Note:</strong> Two's complement allows us to get a number with an inverse signal. One way to do it is to invert the bits of the number in the positive representation and add 1 to it:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">twosComplement</span>(<span class="hljs-params">n</span>) </span>{
  <span class="hljs-keyword">return</span> ~n + <span class="hljs-number">0b1</span>;
}
</code></pre>
<h4 id="heading-left-shift-zero-fill-ltlt">Left shift (zero fill) (<code>&lt;&lt;</code>)</h4>
<p>Shifts the given number of bits to the left, adding zero bits shifted in from the right.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> n = <span class="hljs-number">17</span>;
<span class="hljs-keyword">const</span> result = n &lt;&lt; <span class="hljs-number">1</span>; <span class="hljs-comment">// 34</span>


<span class="hljs-built_in">console</span>.log(createBinaryString(<span class="hljs-number">17</span>));
<span class="hljs-comment">// -&gt; 00000000 00000000 00000000 00010001</span>

<span class="hljs-built_in">console</span>.log(createBinaryString(<span class="hljs-number">34</span>));
<span class="hljs-comment">// -&gt; 00000000 00000000 00000000 00100010</span>
</code></pre>
<p><strong>Note</strong> that the 32nd bit (the leftmost one) is discarded.</p>
<h4 id="heading-right-shift-sign-preserving-gtgt">Right shift (sign preserving) (<code>&gt;&gt;</code>)</h4>
<p>Shifts the given number of bits to the right, preserving the sign when adding bits from the left.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> n = <span class="hljs-number">17</span>;
<span class="hljs-keyword">const</span> result = n &gt;&gt; <span class="hljs-number">1</span>; <span class="hljs-comment">// 8</span>


<span class="hljs-built_in">console</span>.log(createBinaryString(<span class="hljs-number">17</span>));
<span class="hljs-comment">// -&gt; 00000000 00000000 00000000 00010001</span>

<span class="hljs-built_in">console</span>.log(createBinaryString(<span class="hljs-number">8</span>));
<span class="hljs-comment">// -&gt; 00000000 00000000 00000000 00001000</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> n = <span class="hljs-number">-17</span>;
<span class="hljs-keyword">const</span> result = n &gt;&gt; <span class="hljs-number">1</span>; <span class="hljs-comment">// -9</span>

<span class="hljs-built_in">console</span>.log(createBinaryString(<span class="hljs-number">-17</span>));
<span class="hljs-comment">// -&gt; 11111111 11111111 11111111 11101111</span>

<span class="hljs-built_in">console</span>.log(createBinaryString(<span class="hljs-number">-9</span>));
<span class="hljs-comment">// -&gt; 11111111 11111111 11111111 11110111</span>
</code></pre>
<h4 id="heading-right-shift-unsigned-gtgtgt">Right shift (unsigned) (<code>&gt;&gt;&gt;</code>)</h4>
<p>Shifts the given number of bits to the right, adding <code>0</code>s when adding bits in from the left, no matter what the sign is.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> n = <span class="hljs-number">17</span>;
<span class="hljs-keyword">const</span> result = n &gt;&gt;&gt; <span class="hljs-number">1</span>; <span class="hljs-comment">// 8</span>


<span class="hljs-built_in">console</span>.log(createBinaryString(<span class="hljs-number">17</span>));
<span class="hljs-comment">// -&gt; 00000000 00000000 00000000 00010001</span>

<span class="hljs-built_in">console</span>.log(createBinaryString(<span class="hljs-number">8</span>));
<span class="hljs-comment">// -&gt; 00000000 00000000 00000000 00001000</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> n = <span class="hljs-number">-17</span>;
<span class="hljs-keyword">const</span> result = n &gt;&gt;&gt; <span class="hljs-number">1</span>; <span class="hljs-comment">// 2147483639</span>

<span class="hljs-built_in">console</span>.log(createBinaryString(<span class="hljs-number">-17</span>));
<span class="hljs-comment">// -&gt; 11111111 11111111 11111111 11101111</span>

<span class="hljs-built_in">console</span>.log(createBinaryString(<span class="hljs-number">2147483639</span>));
<span class="hljs-comment">// -&gt; 01111111 11111111 11111111 11110111</span>
</code></pre>
<h3 id="heading-getting-a-bit">Getting a bit</h3>
<p>To get a specific bit, we first need to create a <strong>bitmask</strong>. We can do this by shifting <code>1</code> to the left by the index of the bit we want to get. The result is the <strong>AND</strong> of the binary number and the bitmask.</p>
<p>But using JavaScript, we can also do an unsigned right shift by the index to put the bit in the first place (so that we don't get the actual value that is in that position, but whether it is a <code>1</code> or a <code>0</code>):</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getBit</span>(<span class="hljs-params">number, idx</span>) </span>{
  <span class="hljs-keyword">const</span> bitMask = <span class="hljs-number">1</span> &lt;&lt; idx;
  <span class="hljs-keyword">const</span> result = number &amp; bitMask;

  <span class="hljs-keyword">return</span> result &gt;&gt;&gt; idx;
}
</code></pre>
<p>For example, let's try <code>13</code>, which is <code>1101</code> in binary:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> binaryNumber = <span class="hljs-number">0b1101</span>;

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Bit at position 0:'</span>, getBit(binaryNumber, <span class="hljs-number">0</span>));
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Bit at position 1:'</span>, getBit(binaryNumber, <span class="hljs-number">1</span>));
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Bit at position 2:'</span>, getBit(binaryNumber, <span class="hljs-number">2</span>));
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Bit at position 3:'</span>, getBit(binaryNumber, <span class="hljs-number">3</span>));

<span class="hljs-comment">/*
Output:

Bit at position 0: 1
Bit at position 1: 0
Bit at position 2: 1
Bit at position 3: 1
*/</span>
</code></pre>
<h3 id="heading-setting-a-bit">Setting a bit</h3>
<p>If we want to turn a bit to <code>1</code> (in other words, to "<em>set a bit</em>"), we can do a similar thing.</p>
<p>First, we can create a bitmask again by shifting <code>1</code> to the left by the index of the bit we want to set to <code>1</code>. The result is the <strong>OR</strong> of the number and the bitmask:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">setBit</span>(<span class="hljs-params">number, idx</span>) </span>{
  <span class="hljs-keyword">const</span> bitMask = <span class="hljs-number">1</span> &lt;&lt; idx;
  <span class="hljs-keyword">return</span> number | bitMask;    
}
</code></pre>
<p>Remember that in our example <code>13</code> was <code>1101</code> in binary, let's say we want to set the <code>0</code> at index 1:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> binaryNumber = <span class="hljs-number">0b1101</span>;
<span class="hljs-keyword">const</span> newBinaryNumber = setBit(binaryNumber, <span class="hljs-number">1</span>);

<span class="hljs-built_in">console</span>.log(createBinaryString(newBinaryNumber));
<span class="hljs-comment">// -&gt; 00000000 00000000 00000000 00001111</span>

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Bit at position 1:'</span>, getBit(newBinaryNumber, <span class="hljs-number">1</span>));
<span class="hljs-comment">// -&gt; Bit at position 1: 1</span>
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>With some detours here and there, we took a look at fourteen (or fifteen, if you count our <em>interlude</em>) different concepts, from arrays and hashing to bit manipulation.</p>
<p>Although I have to say that eventually, with time, it’s easy to forget all that we learned. But, that's not a problem in itself, because as you might have realized, if there is one idea that should stick with you with this handbook, it’s that problems are best solved when they are broken into smaller parts. And, as with anything else, writing or talking to yourself (see <a target="_blank" href="https://www.freecodecamp.org/news/rubber-duck-debugging/">duck debugging</a>) works miracles.</p>
<p>Now, it's time to take a deep breath.</p>
<p>It was a delightful adventure to explore data structures and algorithms, and hopefully you found some value in it.</p>
<p>Have a beautiful journey ahead, and until then, happy coding.</p>
<h3 id="heading-resources-amp-credits">Resources &amp; Credits</h3>
<p>This handbook was mainly inspired by the amazing <a target="_blank" href="https://medium.com/basecs">BaseCS series</a> by Vaidehi Joshi, which is an incredible resource for learning basic computer science concepts.</p>
<p>The visualization idea was inspired by Lydia Hallie's <a target="_blank" href="https://dev.to/lydiahallie/series/3341">JavaScript Visualized series</a>.</p>
<p>Of course, you can also check out <a target="_blank" href="https://neetcode.io/courses">NeetCode's courses</a> which can be incredibly helpful for a serious study.</p>
<p>There are many other resources to check out if you want to go further, here are some of the ones I used in our exploration:</p>
<ul>
<li><p><a target="_blank" href="http://brilliant.org">brilliant.org</a></p>
</li>
<li><p><a target="_blank" href="http://leetcodethehardway.com">leetcodethehardway.com</a></p>
</li>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference">MDN Web Docs</a></p>
</li>
<li><p><a target="_blank" href="http://baeldung.com/cs">baeldung.com/cs</a></p>
</li>
<li><p><a target="_blank" href="https://lucasfcosta.com/2018/12/25/bitwise-operations.html"><em>The Absolute Essentials for Bit Manipulation in JavaScript</em> by Lucas F. Costa</a></p>
</li>
<li><p><a target="_blank" href="https://condor.depaul.edu/ntomuro/courses/402/notes/heap.html">Heap &amp; HeapSort - Noriko Tomuro</a></p>
</li>
<li><p><a target="_blank" href="https://faculty.cs.niu.edu/~freedman/340/340notes/340heap.htm">Heaps - Professor Reva Freedman</a></p>
</li>
<li><p><a target="_blank" href="https://realpython.com/how-to-implement-python-stack/#using-collectionsdeque-to-create-a-python-stack">"Using <code>collections.deque</code> to Create a Python Stack" - Jim Anderson</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a Visualization for Leetcode's Two Sum Problem – HTML, CSS, & JavaScript Project ]]>
                </title>
                <description>
                    <![CDATA[ With the current state of the job market, there are a lot of people grinding out LeetCode as a way to prepare for technical interviews.  But sometimes it would be nice if there were a visualization showing the algorithms behind these problems.  In th... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-visualization-for-leetcode-two-sum-problem/</link>
                <guid isPermaLink="false">66b8d935d482a18d3e028263</guid>
                
                    <category>
                        <![CDATA[ coding interview ]]>
                    </category>
                
                    <category>
                        <![CDATA[ data visualization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ leetcode ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Jessica Wilkins ]]>
                </dc:creator>
                <pubDate>Tue, 21 Nov 2023 21:08:22 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/11/nubelson-fernandes--Xqckh_XVU4-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>With the current state of the job market, there are a lot of people grinding out <a target="_blank" href="https://leetcode.com/">LeetCode</a> as a way to prepare for technical interviews. </p>
<p>But sometimes it would be nice if there were a visualization showing the algorithms behind these problems. </p>
<p>In this tutorial, we will build out a <a target="_blank" href="https://codepen.io/Jessica-Wilkins-the-decoder/full/eYxVyKN">visualization</a> showing a couple of approaches to a popular LeetCode problem called <a target="_blank" href="https://leetcode.com/problems/two-sum/">Two Sum</a>. We will use vanilla HTML, CSS, and JavaScript to build this project out. </p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-project-setup">Project Setup</a></li>
<li><a class="post-section-overview" href="#heading-how-to-solve-leetcodes-two-sum-problem">How to Solve LeetCode's Two Sum Problem</a><ul>
<li><a class="post-section-overview" href="#heading-description">Description</a></li>
<li><a class="post-section-overview" href="#heading-brute-force-approach">Brute Force Approach</a></li>
<li><a class="post-section-overview" href="#heading-brute-force-javascript-solution-and-time-complexity">Brute Force JavaScript Solution and Time Complexity</a></li>
<li><a class="post-section-overview" href="#heading-map-approach-and-solution">Map Approach and Solution</a></li>
<li><a class="post-section-overview" href="#heading-time-complexity-for-the-map-solution">Time Complexity for the Map Solution</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-overview-for-the-two-sum-visualization">Overview  for the Two Sum Visualization</a></li>
<li><a class="post-section-overview" href="#heading-adding-the-brute-force-visualization">Adding the Brute Force Visualization</a><ul>
<li><a class="post-section-overview" href="#heading-creating-the-const-and-let-variables">Creating the const and let Variables</a></li>
<li><a class="post-section-overview" href="#heading-creating-the-getclassname-function">Creating the getClassName Function</a></li>
<li><a class="post-section-overview" href="#heading-creating-the-bruteforceapproach-function">Creating the bruteForceApproach Function</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-how-to-disable-the-bruteforcesolutionbtn-when-the-animation-is-in-progress">How to Disable the bruteForceSolutionBtn When the Animation is in Progress</a></li>
<li><a class="post-section-overview" href="#heading-adding-the-map-solution-visualization">Adding the Map Solution Visualization</a><ul>
<li><a class="post-section-overview" href="#heading-creating-the-const-variables">Creating the const Variables</a></li>
<li><a class="post-section-overview" href="#heading-creating-the-optimalapproach-async-function">Creating the optimalApproach Async Function</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-how-to-reset-the-table-output-for-the-map-solution">How to Reset the Table Output for the Map Solution</a></li>
<li><a class="post-section-overview" href="#heading-final-solution-code-and-live-example">Final Solution Code and Live Example</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>This tutorial assumes that you have basic knowledge of HTML, CSS and JavaScript. If you haven't gone through a beginner course in any of those languages, then I would suggest starting with these resources:</p>
<ul>
<li><a target="_blank" href="https://www.freecodecamp.org/learn/2022/responsive-web-design/">freeCodeCamp's Responsive Web Design Certification</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/">freeCodeCamp's JavaScript Algorithms and Data Structures Certification</a></li>
</ul>
<p>This tutorial also assumes that you have some basic knowledge of how to work with a code editor or IDE. If not, then I would suggest looking into these resources:</p>
<ul>
<li><a target="_blank" href="https://www.youtube.com/watch?v=WPqXP_kLzpo">Visual Studio Code Crash Course</a></li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-codepen/">How to Use CodePen</a> </li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-replit/">How to Use Replit</a></li>
</ul>
<h2 id="heading-project-setup">Project Setup</h2>
<p>You are free to build out this project in either your local code editor of choice, or through an online IDE or editor like <a target="_blank" href="https://codepen.io/">CodePen</a>, <a target="_blank" href="https://codesandbox.io/">CodeSandbox</a>, or <a target="_blank" href="https://replit.com/">Replit</a>. </p>
<p>This project will consist of three files: <code>index.html</code>, <code>index.js</code>, and <code>styles.css</code>. Since this project is going to mainly focus on JavaScript, I have supplied all of the HTML and CSS in <a target="_blank" href="https://github.com/jdwilkin4/leetcode-two-sum-starter-code">this GitHub repo here</a>. </p>
<p>You are free to <a target="_blank" href="https://www.freecodecamp.org/news/how-to-fork-a-github-repository/">fork</a> and <a target="_blank" href="https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository">clone</a> the repository, or you can copy the code found in the HTML and CSS files and add it to your project.</p>
<p>Once you get your project environment setup, then you should start the local server and see this result on the screen:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Screenshot-2023-11-19-at-4.18.24-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Visualization styles for Leetcode's Two Sum problem</em></p>
<h2 id="heading-how-to-solve-leetcodes-two-sum-problem">How to Solve LeetCode's Two Sum problem</h2>
<p>Before we can build out the visualization for this problem, we need to first understand and solve the problem.</p>
<h3 id="heading-description">Description</h3>
<p>For this problem, you will be given a list of numbers in any order and a target number. The goal is to find the pair of numbers that adds up to the target and return an array of indices for that pair of numbers.</p>
<p>In this example, we have the following list and target number:</p>
<pre><code class="lang-js">[<span class="hljs-number">2</span>,<span class="hljs-number">7</span>,<span class="hljs-number">11</span>,<span class="hljs-number">15</span>]
<span class="hljs-attr">target</span>: <span class="hljs-number">9</span>
</code></pre>
<p>The numbers 2 and 7 equal 9 so we would return <code>[0,1]</code> because that represents the indices for where the pair of numbers can be found in the array. </p>
<p>For this problem, you can assume there will be at least two numbers or more in the array and there will only be <strong>one</strong> possible solution. </p>
<p>So for example you can not have this input here which produces no solution because there are no two numbers in that list that add up to the target.</p>
<pre><code class="lang-js">[<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>]
<span class="hljs-attr">target</span>: <span class="hljs-number">55</span>
</code></pre>
<p>You will also not get an input with multiple solutions. The following input has two answers of <code>[0,1]</code> and <code>[1,2]</code> which goes against the rules of this problem. </p>
<pre><code class="lang-js">[<span class="hljs-number">3</span>,<span class="hljs-number">3</span>,<span class="hljs-number">3</span>]
<span class="hljs-attr">target</span>: <span class="hljs-number">6</span>
</code></pre>
<h3 id="heading-brute-force-approach">Brute Force Approach</h3>
<p>The more intuitive approach would be to start at the beginning of the list of numbers and compare each possible pair of numbers until we find the pair that adds up to the target. </p>
<p>Let's take a look at this example here:</p>
<pre><code class="lang-js">[<span class="hljs-number">11</span>, <span class="hljs-number">15</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>]
<span class="hljs-attr">target</span>:<span class="hljs-number">9</span>
</code></pre>
<p>We can start with the first number in the list (11) and check each possible pair and see if it adds up to the target number (9).</p>
<pre><code><span class="hljs-number">11</span> + <span class="hljs-number">15</span> = <span class="hljs-number">9</span>? NO
<span class="hljs-number">11</span> + <span class="hljs-number">2</span> = <span class="hljs-number">9</span>? NO
<span class="hljs-number">11</span> + <span class="hljs-number">7</span> = <span class="hljs-number">9</span>? NO
</code></pre><p>Since none of those pairs equal the target (9), then we move to the second number in the list (15) and check all possible pairs. There is no need to check 11+15 because we already checked that earlier.</p>
<pre><code><span class="hljs-number">15</span> + <span class="hljs-number">2</span> = <span class="hljs-number">9</span>? NO
<span class="hljs-number">15</span> + <span class="hljs-number">7</span> = <span class="hljs-number">9</span>? NO
</code></pre><p>Since none of those pairs equal the target (9), then we move to the third number in the list (2) and check all possible pairs.</p>
<pre><code><span class="hljs-number">2</span> + <span class="hljs-number">7</span> = <span class="hljs-number">9</span>? YES!!!
</code></pre><p>Now, we have found the pair that adds up to the target we would return <code>[2,3]</code> because that represents the indices for where the pair of numbers can be found in the array. </p>
<h3 id="heading-brute-force-javascript-solution-and-time-complexity">Brute Force JavaScript Solution and Time Complexity</h3>
<p>This solution uses a nested <code>for</code> loop which would be an O(n²) time complexity. The outer loop is used to get the current number in the list and the inner loop is used to check if the sum of the current number and other numbers in the list add up to the target.</p>
<pre><code class="lang-js"><span class="hljs-comment">/**
 * <span class="hljs-doctag">@param <span class="hljs-type">{number[]}</span> <span class="hljs-variable">nums</span></span>
 * <span class="hljs-doctag">@param <span class="hljs-type">{number}</span> <span class="hljs-variable">target</span></span>
 * <span class="hljs-doctag">@return <span class="hljs-type">{number[]}</span></span>
 */</span>

<span class="hljs-keyword">var</span> twoSum = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">nums, target</span>) </span>{
  <span class="hljs-keyword">if</span> (nums.length === <span class="hljs-number">2</span>) <span class="hljs-keyword">return</span> [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>];

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; nums.length; i++) {
    <span class="hljs-keyword">const</span> currentNum = nums[i];
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = i + <span class="hljs-number">1</span>; j &lt; nums.length; j++) {
      <span class="hljs-keyword">if</span> (currentNum + nums[j] === target) <span class="hljs-keyword">return</span> [i, j];
    }
  }
};
</code></pre>
<p><strong>Note:</strong> I have added an additional check in my solution to check if the input array has only two numbers. In that case, we immediately return <code>[0,1]</code> because those are the only possible indices for that test case. </p>
<pre><code class="lang-js"> <span class="hljs-keyword">if</span> (nums.length === <span class="hljs-number">2</span>) <span class="hljs-keyword">return</span> [<span class="hljs-number">0</span>, <span class="hljs-number">1</span>];
</code></pre>
<p>So far, our input arrays have been very small. But if we had an input array of 100, 500, or 1000+ numbers, then it could take a while to find the pair that adds up to the target. </p>
<p>In the next section, we are going to take a look at a solution that utilizes JavaScript's <code>Map</code> object and runs in linear time O(n).</p>
<h3 id="heading-map-approach-and-solution">Map Approach and Solution</h3>
<p>In the brute force approach, we started at the beginning of the array and compared all possible pairs of numbers until we found the pair that added up to the target. But in this approach we can use JavaScript's <code>Map</code> object and one <code>for</code> loop to find that pair.</p>
<p>JavaScript's <code>Map</code> object is a collection of key-value pairs that allows for quick lookups and has built in methods like <code>set()</code>, <code>get()</code> and <code>has()</code>.</p>
<p>Let's work with the same example from earlier:</p>
<pre><code class="lang-js">[<span class="hljs-number">11</span>, <span class="hljs-number">15</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>]
<span class="hljs-attr">target</span>:<span class="hljs-number">9</span>
</code></pre>
<p>We can start looping through the array and look at the current number in the list which would be <code>nums[i]</code>. We also want to create a new <code>map</code> object which will be empty to start.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> map = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();

<span class="hljs-keyword">for</span>(<span class="hljs-keyword">let</span> i=<span class="hljs-number">0</span>; i&lt;nums.length; i++){

}
</code></pre>
<p>Inside our loop, we need to calculate the difference which will be the target minus the current number.</p>
<pre><code class="lang-js">    <span class="hljs-keyword">const</span> map = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();

    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">let</span> i=<span class="hljs-number">0</span>; i&lt;nums.length; i++){
        <span class="hljs-keyword">const</span> difference = target - nums[i]
    }
</code></pre>
<p>Since we know there can only be two numbers that add up to the target, we can check if the difference is in the <code>map</code>. If so, we have found the pair and can return the indices. Otherwise, we can add that current number to the <code>map</code> along with its index.</p>
<pre><code class="lang-js">    <span class="hljs-keyword">const</span> map = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();

    <span class="hljs-keyword">for</span>(<span class="hljs-keyword">let</span> i=<span class="hljs-number">0</span>; i &lt; nums.length; i++) {
        <span class="hljs-keyword">const</span> difference = target - nums[i]

        <span class="hljs-keyword">if</span>(map.has(difference)) {
            <span class="hljs-keyword">return</span> [map.get(difference), i]
        } <span class="hljs-keyword">else</span> {
            map.set(nums[i], i)
        }
    }
</code></pre>
<p>In the following code, the <code>has()</code> method is used to check if the following <code>key</code> is in the <code>map</code> object. This method will return a boolean of true or false. </p>
<pre><code class="lang-js">map.has(difference)
</code></pre>
<p>The <code>get()</code> method is used to return that element from the <code>map</code>. </p>
<pre><code class="lang-js"> <span class="hljs-keyword">if</span>(map.has(difference)) {
   <span class="hljs-keyword">return</span> [map.get(difference), i]
 }
</code></pre>
<p>The <code>set()</code> method will add or update an entry in the <code>map</code> with a key and value.</p>
<pre><code class="lang-js"><span class="hljs-keyword">else</span> {
  map.set(nums[i], i)
}
</code></pre>
<p>Here is the complete code for this approach:</p>
<pre><code class="lang-js"><span class="hljs-comment">/**
 * <span class="hljs-doctag">@param <span class="hljs-type">{number[]}</span> <span class="hljs-variable">nums</span></span>
 * <span class="hljs-doctag">@param <span class="hljs-type">{number}</span> <span class="hljs-variable">target</span></span>
 * <span class="hljs-doctag">@return <span class="hljs-type">{number[]}</span></span>
 */</span>
<span class="hljs-keyword">var</span> twoSum = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">nums, target</span>) </span>{
    <span class="hljs-keyword">if</span>(nums.length === <span class="hljs-number">2</span>) <span class="hljs-keyword">return</span> [<span class="hljs-number">0</span>,<span class="hljs-number">1</span>]

    <span class="hljs-keyword">const</span> map = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();

    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; nums.length; i++) {
        <span class="hljs-keyword">const</span> difference = target - nums[i]

        <span class="hljs-keyword">if</span> (map.has(difference)) {
            <span class="hljs-keyword">return</span> [map.get(difference), i]
        } <span class="hljs-keyword">else</span> {
            map.set(nums[i], i)
        }
    }

};
</code></pre>
<h3 id="heading-time-complexity-for-the-map-solution">Time Complexity for the Map Solution</h3>
<p>This solution would be a linear time complexity O(n). Since we are only using one loop instead of two, we have improved on the time complexity and no longer running in quadratic time O(n²) like we were earlier.</p>
<p>In the next few sections, we are going to start to build out the visualizations for each of these approaches. </p>
<h2 id="heading-overview-for-the-two-sum-visualization">Overview for the Two Sum Visualization</h2>
<p>The goal of this project is to create visualizations for both the map and brute force solutions. </p>
<p>For the brute force solution, we will show what is it like to walk through each pair of numbers until we find the pair that adds up to the target.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Screenshot-2023-11-20-at-8.43.08-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Brute Force approach visualization</em></p>
<p>For the map solution, we will show the map being built out and checking for the pair that adds up to the target. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Screenshot-2023-11-20-at-8.51.40-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Map solution visualization</em></p>
<h2 id="heading-adding-the-brute-force-visualization">Adding the Brute Force Visualization</h2>
<h3 id="heading-creating-the-const-and-let-variables">Creating the <code>const</code> and <code>let</code> Variables</h3>
<p>We first need to create <code>const</code> variables and assign them the result of accessing the HTML elements responsible for displaying the brute force solution button and output.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceSolutionBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"brute-force-visual-btn"</span>);
<span class="hljs-keyword">const</span> bruteForceNumbersOutput = <span class="hljs-built_in">document</span>.querySelector(
  <span class="hljs-string">"#brute-force-output &gt; .numbers-array"</span>
);
<span class="hljs-keyword">const</span> bruteForceTextOutput = <span class="hljs-built_in">document</span>.querySelector(
  <span class="hljs-string">"#brute-force-output &gt; .result-text"</span>
);
</code></pre>
<p>The next step is to create <code>const</code> variables for the test case array and target that will be used for both visualizations. </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> testCaseArray = [<span class="hljs-number">11</span>, <span class="hljs-number">15</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>];
<span class="hljs-keyword">const</span> target = <span class="hljs-number">9</span>;
</code></pre>
<p>Then, we need to create the <code>let</code> variables that will represent the current number we are looking at in the outer loop and the compliment number we are looking at in the inner loop. </p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> currentNum;
<span class="hljs-keyword">let</span> currentCompliment;
</code></pre>
<h3 id="heading-creating-the-getclassname-function">Creating the <code>getClassName</code> Function</h3>
<p>In our visualization we want to show the user the current pair of numbers we are checking by applying different colored borders around them. The current number will have a green border around it and the current compliment number will have a blue border around it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Screenshot-2023-11-20-at-10.02.46-AM.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In order to dynamically update these styles over time, we need to create a function that will be responsible for adding the appropriate classes to the current number and it compliment. </p>
<p>First, start by creating a new <code>getClassName</code> function that takes in a <code>num</code> parameter.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> getClassName = <span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> {

};
</code></pre>
<p>Inside that function, create a <code>switch</code> statement that has the <code>num</code> for the expression we are checking for. </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> getClassName = <span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> {
  <span class="hljs-keyword">switch</span> (num) {

  }
};
</code></pre>
<p>The first <code>case</code> should check for <code>currentNum</code> and return a string for the <code>current-num</code> class.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> getClassName = <span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> {
  <span class="hljs-keyword">switch</span> (num) {
    <span class="hljs-keyword">case</span> currentNum:
      <span class="hljs-keyword">return</span> <span class="hljs-string">"class='current-num'"</span>;
  }
};
</code></pre>
<p>The second <code>case</code> should check for the <code>currentCompliment</code> and return a string for the <code>compliment-num</code> class. </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> getClassName = <span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> {
  <span class="hljs-keyword">switch</span> (num) {
    <span class="hljs-keyword">case</span> currentNum:
      <span class="hljs-keyword">return</span> <span class="hljs-string">"class='current-num'"</span>;
    <span class="hljs-keyword">case</span> currentCompliment:
      <span class="hljs-keyword">return</span> <span class="hljs-string">"class='compliment-num'"</span>;
  }
};
</code></pre>
<p>For the <code>default</code> case, it should return an empty string because we are not going to apply any classes for that element. </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> getClassName = <span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> {
  <span class="hljs-keyword">switch</span> (num) {
    <span class="hljs-keyword">case</span> currentNum:
      <span class="hljs-keyword">return</span> <span class="hljs-string">"class='current-num'"</span>;
    <span class="hljs-keyword">case</span> currentCompliment:
      <span class="hljs-keyword">return</span> <span class="hljs-string">"class='compliment-num'"</span>;
    <span class="hljs-keyword">default</span>:
      <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
  }
};
</code></pre>
<h3 id="heading-creating-the-bruteforceapproach-function">Creating the <code>bruteForceApproach</code> Function</h3>
<p>This function will be responsible for executing the brute force solution and displaying the visualization on the page. </p>
<p>We first need to create the <code>bruteForceApproach</code> function which will be an <code>async</code> function. </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceApproach = <span class="hljs-keyword">async</span> () =&gt; {

};
</code></pre>
<p>Then, we need to add the outer loop for our test case array.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceApproach = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {

  }
};
</code></pre>
<p>Inside the <code>for</code> loop, update the <code>currentNum</code> to assign it the value of the current number we are looking at in the test case array.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceApproach = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    currentNum = testCaseArray[i];
  }
};
</code></pre>
<p>Next, create the inner <code>for</code> loop.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceApproach = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    currentNum = testCaseArray[i];
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = i + <span class="hljs-number">1</span>; j &lt; testCaseArray.length; ++j) {

    }
  }
};
</code></pre>
<p>Inside the inner <code>for</code> loop, update the <code>currentCompliment</code> number and assign it the value of <code>testCaseArray[j]</code>. This is meant to represent each number to the right of the current number. </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceApproach = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    currentNum = testCaseArray[i];
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = i + <span class="hljs-number">1</span>; j &lt; testCaseArray.length; ++j) {
      currentCompliment = testCaseArray[j];
    }
  }
};
</code></pre>
<p>Next, we need to add a <code>setTimeout</code> which will delay the visual changes made to the markup by one second. This is what is going to help create the animated effect of showing the different pairs of numbers. </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceApproach = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    currentNum = testCaseArray[i];
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = i + <span class="hljs-number">1</span>; j &lt; testCaseArray.length; ++j) {
      currentCompliment = testCaseArray[j];
      <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, <span class="hljs-number">1000</span>));
    }
  }
};
</code></pre>
<p>Then we need to update the HTML for the output. Start by assigning the test case array to <code>bruteForceNumbersOutput.innerHTML</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceApproach = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    currentNum = testCaseArray[i];
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = i + <span class="hljs-number">1</span>; j &lt; testCaseArray.length; ++j) {
      currentCompliment = testCaseArray[j];
      <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, <span class="hljs-number">1000</span>));

      bruteForceNumbersOutput.innerHTML = testCaseArray;
    }
  }
};
</code></pre>
<p>Then, we want to use the <code>map</code> method on the array, to create a new array of <code>span</code> elements which represents each number in the array along with the styles. We also need to chain the <code>join</code> method on that to remove the commas that the <code>map</code> method adds when the new array is created.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceApproach = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    currentNum = testCaseArray[i];
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = i + <span class="hljs-number">1</span>; j &lt; testCaseArray.length; ++j) {
      currentCompliment = testCaseArray[j];
      <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, <span class="hljs-number">1000</span>));

      bruteForceNumbersOutput.innerHTML = testCaseArray
        .map(
          <span class="hljs-function">(<span class="hljs-params">num, index</span>) =&gt;</span>
            <span class="hljs-string">`
            &lt;span <span class="hljs-subst">${getClassName(num)}</span>&gt;
            <span class="hljs-subst">${testCaseArray[index]}</span>
            &lt;/span&gt;
          `</span>
        )
        .join(<span class="hljs-string">""</span>);
    }
  }
};
</code></pre>
<p>If we don't find a pair that adds up to the target, then we want to display a message to the user. Update the text content for the <code>bruteForceTextOutput</code> and assign it the following message:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceApproach = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    currentNum = testCaseArray[i];
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = i + <span class="hljs-number">1</span>; j &lt; testCaseArray.length; ++j) {
      currentCompliment = testCaseArray[j];
      <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, <span class="hljs-number">1000</span>));

      bruteForceNumbersOutput.innerHTML = testCaseArray
        .map(
          <span class="hljs-function">(<span class="hljs-params">num, index</span>) =&gt;</span>
            <span class="hljs-string">`
            &lt;span <span class="hljs-subst">${getClassName(num)}</span>&gt;
            <span class="hljs-subst">${testCaseArray[index]}</span>
            &lt;/span&gt;
          `</span>
        )
        .join(<span class="hljs-string">""</span>);

      bruteForceTextOutput.textContent = <span class="hljs-string">`Does the sum of <span class="hljs-subst">${currentNum}</span> + <span class="hljs-subst">${currentCompliment}</span> equal <span class="hljs-subst">${target}</span>? NO!`</span>;
    }
  }
};
</code></pre>
<p>The last piece is to add a condition that checks if we found the pair of numbers that adds up to the target. If so, then we can display that final indices array and <code>return</code> from the function. </p>
<pre><code class="lang-js">  <span class="hljs-keyword">if</span> (currentNum + currentCompliment === target) {
      bruteForceTextOutput.textContent = <span class="hljs-string">`Final indices: [<span class="hljs-subst">${i}</span>, <span class="hljs-subst">${j}</span>]`</span>;
      <span class="hljs-keyword">return</span>;
  }
</code></pre>
<p>To test out the brute force visualization, we will need to add an event listener to the <code>bruteForceSolutionBtn</code>. The event listener should listen for a <code>"click"</code> event and should reference the <code>bruteForceApproach</code> function.</p>
<pre><code class="lang-js">bruteForceSolutionBtn.addEventListener(<span class="hljs-string">"click"</span>, bruteForceApproach);
</code></pre>
<p>This should be your complete code so far:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceSolutionBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"brute-force-visual-btn"</span>);
<span class="hljs-keyword">const</span> bruteForceNumbersOutput = <span class="hljs-built_in">document</span>.querySelector(
  <span class="hljs-string">"#brute-force-output &gt; .numbers-array"</span>
);
<span class="hljs-keyword">const</span> bruteForceTextOutput = <span class="hljs-built_in">document</span>.querySelector(
  <span class="hljs-string">"#brute-force-output &gt; .result-text"</span>
);
<span class="hljs-keyword">const</span> testCaseArray = [<span class="hljs-number">11</span>, <span class="hljs-number">15</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>];
<span class="hljs-keyword">const</span> target = <span class="hljs-number">9</span>;
<span class="hljs-keyword">let</span> currentNum;
<span class="hljs-keyword">let</span> currentCompliment;

<span class="hljs-keyword">const</span> getClassName = <span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> {
  <span class="hljs-keyword">switch</span> (num) {
    <span class="hljs-keyword">case</span> currentNum:
      <span class="hljs-keyword">return</span> <span class="hljs-string">"class='current-num'"</span>;
    <span class="hljs-keyword">case</span> currentCompliment:
      <span class="hljs-keyword">return</span> <span class="hljs-string">"class='compliment-num'"</span>;
    <span class="hljs-keyword">default</span>:
      <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
  }
};

<span class="hljs-keyword">const</span> bruteForceApproach = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    currentNum = testCaseArray[i];
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = i + <span class="hljs-number">1</span>; j &lt; testCaseArray.length; ++j) {
      currentCompliment = testCaseArray[j];
      <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, <span class="hljs-number">1000</span>));

      bruteForceNumbersOutput.innerHTML = testCaseArray
        .map(
          <span class="hljs-function">(<span class="hljs-params">num, index</span>) =&gt;</span>
            <span class="hljs-string">`
            &lt;span <span class="hljs-subst">${getClassName(num)}</span>&gt;
            <span class="hljs-subst">${testCaseArray[index]}</span>
            &lt;/span&gt;
          `</span>
        )
        .join(<span class="hljs-string">""</span>);

      bruteForceTextOutput.textContent = <span class="hljs-string">`Does the sum of <span class="hljs-subst">${currentNum}</span> + <span class="hljs-subst">${currentCompliment}</span> equal <span class="hljs-subst">${target}</span>? NO!`</span>;

      <span class="hljs-keyword">if</span> (currentNum + currentCompliment === target) {
        bruteForceTextOutput.textContent = <span class="hljs-string">`Final indices: [<span class="hljs-subst">${i}</span>, <span class="hljs-subst">${j}</span>]`</span>;
        <span class="hljs-keyword">return</span>;
      }
    }
  }
};

bruteForceSolutionBtn.addEventListener(<span class="hljs-string">"click"</span>, bruteForceApproach);
</code></pre>
<p>Try out your visualization by clicking on the "Show Visualization" button for the Brute force approach. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Screenshot-2023-11-20-at-10.42.51-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Result of clicking the "show visualization" button for brute force approach</em></p>
<h2 id="heading-how-to-disable-the-bruteforcesolutionbtn-when-the-animation-is-in-progress">How to Disable the <code>bruteForceSolutionBtn</code> When the Animation is in Progress</h2>
<p>If you try to click on the <code>bruteForceSolutionBtn</code> multiple times in a row, you will see glitches in the animation. To fix that, we should disable the button when the animation is running and then re-enable it when the animation is complete. </p>
<p>Inside the <code>bruteForceApproach</code> function, set the disabled attribute for the <code>bruteForceSolutionBtn</code>. </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceApproach = <span class="hljs-keyword">async</span> () =&gt; {
  bruteForceSolutionBtn.setAttribute(<span class="hljs-string">"disabled"</span>, <span class="hljs-string">""</span>);
</code></pre>
<p>Inside the <code>if</code> statement, remove the disabled attribute for the <code>bruteForceSolutionBtn</code>.</p>
<pre><code class="lang-js">   <span class="hljs-keyword">if</span> (currentNum + currentCompliment === target) {
        bruteForceTextOutput.textContent = <span class="hljs-string">`Final indices: [<span class="hljs-subst">${i}</span>, <span class="hljs-subst">${j}</span>]`</span>;
        bruteForceSolutionBtn.removeAttribute(<span class="hljs-string">"disabled"</span>);
        <span class="hljs-keyword">return</span>;
   }
</code></pre>
<p>Here is the complete code with the fix:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceSolutionBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"brute-force-visual-btn"</span>);
<span class="hljs-keyword">const</span> bruteForceNumbersOutput = <span class="hljs-built_in">document</span>.querySelector(
  <span class="hljs-string">"#brute-force-output &gt; .numbers-array"</span>
);
<span class="hljs-keyword">const</span> bruteForceTextOutput = <span class="hljs-built_in">document</span>.querySelector(
  <span class="hljs-string">"#brute-force-output &gt; .result-text"</span>
);
<span class="hljs-keyword">const</span> testCaseArray = [<span class="hljs-number">11</span>, <span class="hljs-number">15</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>];
<span class="hljs-keyword">const</span> target = <span class="hljs-number">9</span>;
<span class="hljs-keyword">let</span> currentNum;
<span class="hljs-keyword">let</span> currentCompliment;

<span class="hljs-keyword">const</span> getClassName = <span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> {
  <span class="hljs-keyword">switch</span> (num) {
    <span class="hljs-keyword">case</span> currentNum:
      <span class="hljs-keyword">return</span> <span class="hljs-string">"class='current-num'"</span>;
    <span class="hljs-keyword">case</span> currentCompliment:
      <span class="hljs-keyword">return</span> <span class="hljs-string">"class='compliment-num'"</span>;
    <span class="hljs-keyword">default</span>:
      <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
  }
};

<span class="hljs-keyword">const</span> bruteForceApproach = <span class="hljs-keyword">async</span> () =&gt; {
  bruteForceSolutionBtn.setAttribute(<span class="hljs-string">"disabled"</span>, <span class="hljs-string">""</span>);

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    currentNum = testCaseArray[i];
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = i + <span class="hljs-number">1</span>; j &lt; testCaseArray.length; ++j) {
      currentCompliment = testCaseArray[j];
      <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, <span class="hljs-number">1000</span>));

      bruteForceNumbersOutput.innerHTML = testCaseArray
        .map(
          <span class="hljs-function">(<span class="hljs-params">num, index</span>) =&gt;</span>
            <span class="hljs-string">`
            &lt;span <span class="hljs-subst">${getClassName(num)}</span>&gt;
            <span class="hljs-subst">${testCaseArray[index]}</span>
            &lt;/span&gt;
          `</span>
        )
        .join(<span class="hljs-string">""</span>);

      bruteForceTextOutput.textContent = <span class="hljs-string">`Does the sum of <span class="hljs-subst">${currentNum}</span> + <span class="hljs-subst">${currentCompliment}</span> equal <span class="hljs-subst">${target}</span>? NO!`</span>;

      <span class="hljs-keyword">if</span> (currentNum + currentCompliment === target) {
        bruteForceTextOutput.textContent = <span class="hljs-string">`Final indices: [<span class="hljs-subst">${i}</span>, <span class="hljs-subst">${j}</span>]`</span>;
        bruteForceSolutionBtn.removeAttribute(<span class="hljs-string">"disabled"</span>);
        <span class="hljs-keyword">return</span>;
      }
    }
  }
};

bruteForceSolutionBtn.addEventListener(<span class="hljs-string">"click"</span>, bruteForceApproach);
</code></pre>
<p>Try out the visualization again, and now you should see that the button is disabled when the animation is running.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Screenshot-2023-11-20-at-10.56.36-AM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Image showing how button is disabled when animation is showing</em></p>
<h2 id="heading-adding-the-map-solution-visualization">Adding the Map Solution Visualization</h2>
<h3 id="heading-creating-the-const-variables">Creating the <code>const</code> Variables</h3>
<p>We are going to create some new <code>const</code> variables which represent the optimal solution button element, output, and table elements for the animation.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> optimalSolutionBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"optimal-visual-btn"</span>);
<span class="hljs-keyword">const</span> currentValueOutput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"current-value-output"</span>);
<span class="hljs-keyword">const</span> finalOptimalSolutionResult = <span class="hljs-built_in">document</span>.getElementById(
  <span class="hljs-string">"final-optimal-result"</span>
);
<span class="hljs-keyword">const</span> table = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"table-output"</span>);
<span class="hljs-keyword">const</span> tableBodyOutput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"map-table-body"</span>);
</code></pre>
<p>Here is the complete list of variable declarations for both visualizations:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceSolutionBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"brute-force-visual-btn"</span>);
<span class="hljs-keyword">const</span> bruteForceNumbersOutput = <span class="hljs-built_in">document</span>.querySelector(
  <span class="hljs-string">"#brute-force-output &gt; .numbers-array"</span>
);
<span class="hljs-keyword">const</span> bruteForceTextOutput = <span class="hljs-built_in">document</span>.querySelector(
  <span class="hljs-string">"#brute-force-output &gt; .result-text"</span>
);
<span class="hljs-keyword">const</span> optimalSolutionBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"optimal-visual-btn"</span>);
<span class="hljs-keyword">const</span> currentValueOutput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"current-value-output"</span>);
<span class="hljs-keyword">const</span> finalOptimalSolutionResult = <span class="hljs-built_in">document</span>.getElementById(
  <span class="hljs-string">"final-optimal-result"</span>
);
<span class="hljs-keyword">const</span> table = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"table-output"</span>);
<span class="hljs-keyword">const</span> tableBodyOutput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"map-table-body"</span>);

<span class="hljs-keyword">const</span> testCaseArray = [<span class="hljs-number">11</span>, <span class="hljs-number">15</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>];
<span class="hljs-keyword">const</span> target = <span class="hljs-number">9</span>;
<span class="hljs-keyword">let</span> currentNum;
<span class="hljs-keyword">let</span> currentCompliment;
</code></pre>
<h3 id="heading-creating-the-optimalapproach-async-function">Creating the <code>optimalApproach</code> Async Function</h3>
<p>The first step is to create the new <code>optimalApproach</code> function which will be an <code>async</code> function. You can add this below your <code>bruteForceApproach</code> function.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> optimalApproach = <span class="hljs-keyword">async</span> () =&gt; {

};
</code></pre>
<p>Just like the <code>bruteForceApproach</code> function, we want to disable the button when the animation starts to prevent users from clicking it multiple times and breaking the animation.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> optimalApproach = <span class="hljs-keyword">async</span> () =&gt; {
  optimalSolutionBtn.setAttribute(<span class="hljs-string">"disabled"</span>, <span class="hljs-string">""</span>);
};
</code></pre>
<p>When the page first loads, the table is hidden by default. We want to show the table element when the animation starts.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> optimalApproach = <span class="hljs-keyword">async</span> () =&gt; {
  optimalSolutionBtn.setAttribute(<span class="hljs-string">"disabled"</span>, <span class="hljs-string">""</span>);
  table.style.display = <span class="hljs-string">"block"</span>;
};
</code></pre>
<p>Each time we run this animation, we want to display messages to the user on if we have found the correct pair or not. At the beginning of the animation, we want to clear the previous output. </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> optimalApproach = <span class="hljs-keyword">async</span> () =&gt; {
  optimalSolutionBtn.setAttribute(<span class="hljs-string">"disabled"</span>, <span class="hljs-string">""</span>);
  table.style.display = <span class="hljs-string">"block"</span>;
  currentValueOutput.innerHTML = <span class="hljs-string">""</span>;
};
</code></pre>
<p>Then, we need to create an empty <code>map</code> object which will eventually be updated over time in the <code>for</code> loop.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> optimalApproach = <span class="hljs-keyword">async</span> () =&gt; {
  optimalSolutionBtn.setAttribute(<span class="hljs-string">"disabled"</span>, <span class="hljs-string">""</span>);
  table.style.display = <span class="hljs-string">"block"</span>;
  currentValueOutput.innerHTML = <span class="hljs-string">""</span>;
  <span class="hljs-keyword">const</span> map = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();
};
</code></pre>
<p>Next, we need to create a <code>for</code> loop which will be responsible for looping through each number in the array and updating the animation overtime. </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> optimalApproach = <span class="hljs-keyword">async</span> () =&gt; {
  optimalSolutionBtn.setAttribute(<span class="hljs-string">"disabled"</span>, <span class="hljs-string">""</span>);
  table.style.display = <span class="hljs-string">"block"</span>;
  currentValueOutput.innerHTML = <span class="hljs-string">""</span>;
  <span class="hljs-keyword">const</span> map = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {

  }
};
</code></pre>
<p>Inside the loop, we need to add the expression for calculating the difference.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> optimalApproach = <span class="hljs-keyword">async</span> () =&gt; {
  optimalSolutionBtn.setAttribute(<span class="hljs-string">"disabled"</span>, <span class="hljs-string">""</span>);
  table.style.display = <span class="hljs-string">"block"</span>;
  currentValueOutput.innerHTML = <span class="hljs-string">""</span>;
  <span class="hljs-keyword">const</span> map = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    <span class="hljs-keyword">const</span> difference = target - testCaseArray[i];
  }
};
</code></pre>
<p>Then, we need to add a <code>setTimeout</code> which will delay the changes by 2 seconds in the HTML markup and help with the animation effect.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> optimalApproach = <span class="hljs-keyword">async</span> () =&gt; {
  optimalSolutionBtn.setAttribute(<span class="hljs-string">"disabled"</span>, <span class="hljs-string">""</span>);
  table.style.display = <span class="hljs-string">"block"</span>;
  currentValueOutput.innerHTML = <span class="hljs-string">""</span>;
  <span class="hljs-keyword">const</span> map = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    <span class="hljs-keyword">const</span> difference = target - testCaseArray[i];

    <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, <span class="hljs-number">2000</span>));
  }
};
</code></pre>
<p>We then need to add an <code>if</code> statement to check if the map has the difference value.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> optimalApproach = <span class="hljs-keyword">async</span> () =&gt; {
  optimalSolutionBtn.setAttribute(<span class="hljs-string">"disabled"</span>, <span class="hljs-string">""</span>);
  table.style.display = <span class="hljs-string">"block"</span>;
  currentValueOutput.innerHTML = <span class="hljs-string">""</span>;
  <span class="hljs-keyword">const</span> map = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    <span class="hljs-keyword">const</span> difference = target - testCaseArray[i];

    <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, <span class="hljs-number">2000</span>));

    <span class="hljs-keyword">if</span> (map.has(difference)) {

    }
  }
};
</code></pre>
<p>Inside the <code>if</code> statement, we need to update the text content to show the final indices array result on the screen. We will use the <code>get</code> method to get the index value from the <code>map</code>. </p>
<pre><code class="lang-js"> <span class="hljs-keyword">if</span> (map.has(difference)) {
      finalOptimalSolutionResult.textContent = <span class="hljs-string">`Final indices: [<span class="hljs-subst">${map.get(
        difference
      )}</span>, <span class="hljs-subst">${i}</span>]`</span>;
 }
</code></pre>
<p>We also need to update the output for displaying a message that shows we have found the pair of numbers that adds up to the target. </p>
<pre><code class="lang-js">  <span class="hljs-keyword">if</span> (map.has(difference)) {
      finalOptimalSolutionResult.textContent = <span class="hljs-string">`Final indices: [<span class="hljs-subst">${map.get(
        difference
      )}</span>, <span class="hljs-subst">${i}</span>]`</span>;
      currentValueOutput.innerHTML = <span class="hljs-string">`
      &lt;p&gt;Difference(<span class="hljs-subst">${difference}</span>) = target(<span class="hljs-subst">${target}</span>) - current number(<span class="hljs-subst">${testCaseArray[i]}</span>)&lt;/p&gt;
      &lt;p&gt;Is the difference(<span class="hljs-subst">${difference}</span>) in our map? YES, we found that pair of numbers that add up to the target.&lt;/p&gt;
    `</span>;
  }
</code></pre>
<p>We also need to remove the disabled attribute from the <code>optimalSolutionBtn</code> and return from the function. </p>
<pre><code class="lang-js">  <span class="hljs-keyword">if</span> (map.has(difference)) {
      finalOptimalSolutionResult.textContent = <span class="hljs-string">`Final indices: [<span class="hljs-subst">${map.get(
        difference
      )}</span>, <span class="hljs-subst">${i}</span>]`</span>;
      currentValueOutput.innerHTML = <span class="hljs-string">`
      &lt;p&gt;Difference(<span class="hljs-subst">${difference}</span>) = target(<span class="hljs-subst">${target}</span>) - current number(<span class="hljs-subst">${testCaseArray[i]}</span>)&lt;/p&gt;
      &lt;p&gt;Is the difference(<span class="hljs-subst">${difference}</span>) in our map? YES, we found that pair of numbers that add up to the target.&lt;/p&gt;
    `</span>;
      optimalSolutionBtn.removeAttribute(<span class="hljs-string">"disabled"</span>);
      <span class="hljs-keyword">return</span>;
  }
</code></pre>
<p>If the pair has not been found, then we need to add an <code>else</code> clause.</p>
<pre><code class="lang-js">  <span class="hljs-keyword">if</span> (map.has(difference)) {
      finalOptimalSolutionResult.textContent = <span class="hljs-string">`Final indices: [<span class="hljs-subst">${map.get(
        difference
      )}</span>, <span class="hljs-subst">${i}</span>]`</span>;
      currentValueOutput.innerHTML = <span class="hljs-string">`
      &lt;p&gt;Difference(<span class="hljs-subst">${difference}</span>) = target(<span class="hljs-subst">${target}</span>) - current number(<span class="hljs-subst">${testCaseArray[i]}</span>)&lt;/p&gt;
      &lt;p&gt;Is the difference(<span class="hljs-subst">${difference}</span>) in our map? YES, we found that pair of numbers that add up to the target.&lt;/p&gt;
    `</span>;
      optimalSolutionBtn.removeAttribute(<span class="hljs-string">"disabled"</span>);
      <span class="hljs-keyword">return</span>;
  } <span class="hljs-keyword">else</span> {

  }
</code></pre>
<p>Inside the <code>else</code> clause, we need to update the message to show that we have not found the pair and that the current number <code>testCaseArray[i]</code> is going to be added to the <code>map</code> along with its index value.</p>
<pre><code class="lang-js"><span class="hljs-keyword">else</span> {
      currentValueOutput.innerHTML = <span class="hljs-string">`
        &lt;p&gt;Difference(<span class="hljs-subst">${difference}</span>) = target(<span class="hljs-subst">${target}</span>) - current number(<span class="hljs-subst">${testCaseArray[i]}</span>)&lt;/p&gt;
        &lt;p&gt;Is the difference(<span class="hljs-subst">${difference}</span>) in our map? No.&lt;/p&gt;
        &lt;p&gt;Add the current number <span class="hljs-subst">${testCaseArray[i]}</span> to our map.&lt;/p&gt;
      `</span>;
}
</code></pre>
<p>We then need to update the table output with the current number and its index value.</p>
<pre><code class="lang-js"><span class="hljs-keyword">else</span> {
      currentValueOutput.innerHTML = <span class="hljs-string">`
        &lt;p&gt;Difference(<span class="hljs-subst">${difference}</span>) = target(<span class="hljs-subst">${target}</span>) - current number(<span class="hljs-subst">${testCaseArray[i]}</span>)&lt;/p&gt;
        &lt;p&gt;Is the difference(<span class="hljs-subst">${difference}</span>) in our map? No.&lt;/p&gt;
        &lt;p&gt;Add the current number <span class="hljs-subst">${testCaseArray[i]}</span> to our map.&lt;/p&gt;
      `</span>;
      tableBodyOutput.innerHTML += <span class="hljs-string">`
      &lt;tr&gt;
        &lt;td&gt;<span class="hljs-subst">${testCaseArray[i]}</span>&lt;/td&gt;
        &lt;td&gt;<span class="hljs-subst">${i}</span>&lt;/td&gt;
      &lt;/tr&gt;
    `</span>;
}
</code></pre>
<p>Lastly, use the <code>set</code> method to set the current number and index value in the <code>map</code>.</p>
<pre><code class="lang-js"><span class="hljs-keyword">else</span> {
      currentValueOutput.innerHTML = <span class="hljs-string">`
        &lt;p&gt;Difference(<span class="hljs-subst">${difference}</span>) = target(<span class="hljs-subst">${target}</span>) - current number(<span class="hljs-subst">${testCaseArray[i]}</span>)&lt;/p&gt;
        &lt;p&gt;Is the difference(<span class="hljs-subst">${difference}</span>) in our map? No.&lt;/p&gt;
        &lt;p&gt;Add the current number <span class="hljs-subst">${testCaseArray[i]}</span> to our map.&lt;/p&gt;
      `</span>;
      tableBodyOutput.innerHTML += <span class="hljs-string">`
      &lt;tr&gt;
        &lt;td&gt;<span class="hljs-subst">${testCaseArray[i]}</span>&lt;/td&gt;
        &lt;td&gt;<span class="hljs-subst">${i}</span>&lt;/td&gt;
      &lt;/tr&gt;
    `</span>;
      map.set(testCaseArray[i], i);
}
</code></pre>
<p>Here is the complete code for your <code>optimalApproach</code> function.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> optimalApproach = <span class="hljs-keyword">async</span> () =&gt; {
  optimalSolutionBtn.setAttribute(<span class="hljs-string">"disabled"</span>, <span class="hljs-string">""</span>);
  table.style.display = <span class="hljs-string">"block"</span>;
  currentValueOutput.innerHTML = <span class="hljs-string">""</span>;
  <span class="hljs-keyword">const</span> map = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    <span class="hljs-keyword">const</span> difference = target - testCaseArray[i];

    <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, <span class="hljs-number">2000</span>));

    <span class="hljs-keyword">if</span> (map.has(difference)) {
      finalOptimalSolutionResult.textContent = <span class="hljs-string">`Final indices: [<span class="hljs-subst">${map.get(
        difference
      )}</span>, <span class="hljs-subst">${i}</span>]`</span>;
      currentValueOutput.innerHTML = <span class="hljs-string">`
      &lt;p&gt;Difference(<span class="hljs-subst">${difference}</span>) = target(<span class="hljs-subst">${target}</span>) - current number(<span class="hljs-subst">${testCaseArray[i]}</span>)&lt;/p&gt;
      &lt;p&gt;Is the difference(<span class="hljs-subst">${difference}</span>) in our map? YES, we found that pair of numbers that add up to the target.&lt;/p&gt;
    `</span>;
      optimalSolutionBtn.removeAttribute(<span class="hljs-string">"disabled"</span>);
      <span class="hljs-keyword">return</span>;
    } <span class="hljs-keyword">else</span> {
      currentValueOutput.innerHTML = <span class="hljs-string">`
        &lt;p&gt;Difference(<span class="hljs-subst">${difference}</span>) = target(<span class="hljs-subst">${target}</span>) - current number(<span class="hljs-subst">${testCaseArray[i]}</span>)&lt;/p&gt;
        &lt;p&gt;Is the difference(<span class="hljs-subst">${difference}</span>) in our map? No.&lt;/p&gt;
        &lt;p&gt;Add the current number <span class="hljs-subst">${testCaseArray[i]}</span> to our map.&lt;/p&gt;
      `</span>;
      tableBodyOutput.innerHTML += <span class="hljs-string">`
      &lt;tr&gt;
        &lt;td&gt;<span class="hljs-subst">${testCaseArray[i]}</span>&lt;/td&gt;
        &lt;td&gt;<span class="hljs-subst">${i}</span>&lt;/td&gt;
      &lt;/tr&gt;
    `</span>;
      map.set(testCaseArray[i], i);
    }
  }
};
</code></pre>
<p>To test out this visualization, add an event listener to the <code>optimalSolutionBtn</code> and pass in the <code>"click"</code> event and <code>optimalApproach</code> function reference. </p>
<pre><code class="lang-js">optimalSolutionBtn.addEventListener(<span class="hljs-string">"click"</span>, optimalApproach);
</code></pre>
<p>When you click on the "Show Visualization" button for the map solution, you should see the animation, as shown below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Screenshot-2023-11-20-at-12.05.05-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Visualization for map solution</em></p>
<h2 id="heading-how-to-reset-the-table-output-for-the-map-solution">How to Reset the Table Output for the Map Solution</h2>
<p>If you try to run the animation multiple times, then you will see that the table shows the results from the previous run.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2023/11/Screenshot-2023-11-20-at-12.09.35-PM.png" alt="Image" width="600" height="400" loading="lazy">
<em>Table showing results from the previous run</em></p>
<p>To fix this, we can reset the table before each run of the animation. Start by creating a <code>resetTable</code> function above your <code>optimalApproach</code> function.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> resetTable = <span class="hljs-function">() =&gt;</span> {

};

<span class="hljs-keyword">const</span> optimalApproach = <span class="hljs-keyword">async</span> () =&gt; {
    .........
</code></pre>
<p>Inside that function, clear out the table and final text results. </p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> resetTable = <span class="hljs-function">() =&gt;</span> {
  tableBodyOutput.innerHTML = <span class="hljs-string">""</span>;
  finalOptimalSolutionResult.textContent = <span class="hljs-string">""</span>;
};
</code></pre>
<p>Call the <code>resetTable</code> function inside your <code>optimalApproach</code> function in order to see the results of resetting the table.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> optimalApproach = <span class="hljs-keyword">async</span> () =&gt; {
  resetTable();
  optimalSolutionBtn.setAttribute(<span class="hljs-string">"disabled"</span>, <span class="hljs-string">""</span>);
    ...........
</code></pre>
<p>Test out your animation again, and now you should see that the table results reset before each new animation run. </p>
<h2 id="heading-final-solution-code-and-live-example">Final Solution Code and Live Example</h2>
<p>Here is the complete JavaScript solution code for both visualizations:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bruteForceSolutionBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"brute-force-visual-btn"</span>);
<span class="hljs-keyword">const</span> bruteForceNumbersOutput = <span class="hljs-built_in">document</span>.querySelector(
  <span class="hljs-string">"#brute-force-output &gt; .numbers-array"</span>
);
<span class="hljs-keyword">const</span> bruteForceTextOutput = <span class="hljs-built_in">document</span>.querySelector(
  <span class="hljs-string">"#brute-force-output &gt; .result-text"</span>
);
<span class="hljs-keyword">const</span> optimalSolutionBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"optimal-visual-btn"</span>);
<span class="hljs-keyword">const</span> currentValueOutput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"current-value-output"</span>);
<span class="hljs-keyword">const</span> finalOptimalSolutionResult = <span class="hljs-built_in">document</span>.getElementById(
  <span class="hljs-string">"final-optimal-result"</span>
);
<span class="hljs-keyword">const</span> table = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"table-output"</span>);
<span class="hljs-keyword">const</span> tableBodyOutput = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"map-table-body"</span>);

<span class="hljs-keyword">const</span> testCaseArray = [<span class="hljs-number">11</span>, <span class="hljs-number">15</span>, <span class="hljs-number">2</span>, <span class="hljs-number">7</span>];
<span class="hljs-keyword">const</span> target = <span class="hljs-number">9</span>;
<span class="hljs-keyword">let</span> currentNum;
<span class="hljs-keyword">let</span> currentCompliment;

<span class="hljs-keyword">const</span> getClassName = <span class="hljs-function">(<span class="hljs-params">num</span>) =&gt;</span> {
  <span class="hljs-keyword">switch</span> (num) {
    <span class="hljs-keyword">case</span> currentNum:
      <span class="hljs-keyword">return</span> <span class="hljs-string">"class='current-num'"</span>;
    <span class="hljs-keyword">case</span> currentCompliment:
      <span class="hljs-keyword">return</span> <span class="hljs-string">"class='compliment-num'"</span>;
    <span class="hljs-keyword">default</span>:
      <span class="hljs-keyword">return</span> <span class="hljs-string">""</span>;
  }
};

<span class="hljs-keyword">const</span> bruteForceApproach = <span class="hljs-keyword">async</span> () =&gt; {
  bruteForceSolutionBtn.setAttribute(<span class="hljs-string">"disabled"</span>, <span class="hljs-string">""</span>);

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    currentNum = testCaseArray[i];
    <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> j = i + <span class="hljs-number">1</span>; j &lt; testCaseArray.length; ++j) {
      currentCompliment = testCaseArray[j];
      <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, <span class="hljs-number">1000</span>));

      bruteForceNumbersOutput.innerHTML = testCaseArray
        .map(
          <span class="hljs-function">(<span class="hljs-params">num, index</span>) =&gt;</span>
            <span class="hljs-string">`
              &lt;span <span class="hljs-subst">${getClassName(num)}</span>&gt;
              <span class="hljs-subst">${testCaseArray[index]}</span>
              &lt;/span&gt;
            `</span>
        )
        .join(<span class="hljs-string">""</span>);

      bruteForceTextOutput.textContent = <span class="hljs-string">`Does the sum of <span class="hljs-subst">${currentNum}</span> + <span class="hljs-subst">${currentCompliment}</span> equal <span class="hljs-subst">${target}</span>? NO!`</span>;

      <span class="hljs-keyword">if</span> (currentNum + currentCompliment === target) {
        bruteForceTextOutput.textContent = <span class="hljs-string">`Final indices: [<span class="hljs-subst">${i}</span>, <span class="hljs-subst">${j}</span>]`</span>;
        bruteForceSolutionBtn.removeAttribute(<span class="hljs-string">"disabled"</span>);
        <span class="hljs-keyword">return</span>;
      }
    }
  }
};

<span class="hljs-keyword">const</span> resetTable = <span class="hljs-function">() =&gt;</span> {
  tableBodyOutput.innerHTML = <span class="hljs-string">""</span>;
  finalOptimalSolutionResult.textContent = <span class="hljs-string">""</span>;
};

<span class="hljs-keyword">const</span> optimalApproach = <span class="hljs-keyword">async</span> () =&gt; {
  resetTable();
  optimalSolutionBtn.setAttribute(<span class="hljs-string">"disabled"</span>, <span class="hljs-string">""</span>);
  table.style.display = <span class="hljs-string">"block"</span>;
  currentValueOutput.innerHTML = <span class="hljs-string">""</span>;
  <span class="hljs-keyword">const</span> map = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();

  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; testCaseArray.length; ++i) {
    <span class="hljs-keyword">const</span> difference = target - testCaseArray[i];

    <span class="hljs-keyword">await</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve</span>) =&gt;</span> <span class="hljs-built_in">setTimeout</span>(resolve, <span class="hljs-number">2000</span>));

    <span class="hljs-keyword">if</span> (map.has(difference)) {
      finalOptimalSolutionResult.textContent = <span class="hljs-string">`Final indices: [<span class="hljs-subst">${map.get(
        difference
      )}</span>, <span class="hljs-subst">${i}</span>]`</span>;
      currentValueOutput.innerHTML = <span class="hljs-string">`
      &lt;p&gt;Difference(<span class="hljs-subst">${difference}</span>) = target(<span class="hljs-subst">${target}</span>) - current number(<span class="hljs-subst">${testCaseArray[i]}</span>)&lt;/p&gt;
      &lt;p&gt;Is the difference(<span class="hljs-subst">${difference}</span>) in our map? YES, we found that pair of numbers that add up to the target.&lt;/p&gt;
    `</span>;
      optimalSolutionBtn.removeAttribute(<span class="hljs-string">"disabled"</span>);
      <span class="hljs-keyword">return</span>;
    } <span class="hljs-keyword">else</span> {
      currentValueOutput.innerHTML = <span class="hljs-string">`
        &lt;p&gt;Difference(<span class="hljs-subst">${difference}</span>) = target(<span class="hljs-subst">${target}</span>) - current number(<span class="hljs-subst">${testCaseArray[i]}</span>)&lt;/p&gt;
        &lt;p&gt;Is the difference(<span class="hljs-subst">${difference}</span>) in our map? No.&lt;/p&gt;
        &lt;p&gt;Add the current number <span class="hljs-subst">${testCaseArray[i]}</span> to our map.&lt;/p&gt;
      `</span>;
      tableBodyOutput.innerHTML += <span class="hljs-string">`
        &lt;tr&gt;
          &lt;td&gt;<span class="hljs-subst">${testCaseArray[i]}</span>&lt;/td&gt;
          &lt;td&gt;<span class="hljs-subst">${i}</span>&lt;/td&gt;
        &lt;/tr&gt;
      `</span>;
      map.set(testCaseArray[i], i);
    }
  }
};

bruteForceSolutionBtn.addEventListener(<span class="hljs-string">"click"</span>, bruteForceApproach);
optimalSolutionBtn.addEventListener(<span class="hljs-string">"click"</span>, optimalApproach);
</code></pre>
<p>Here is a <a target="_blank" href="https://codepen.io/Jessica-Wilkins-the-decoder/full/eYxVyKN">link</a> again to the final live result on CodePen.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope you enjoyed that project and learned a little bit more about how the Two Sum problem works. </p>
<p>I encourage you to play around with the project and maybe add some new features on your own like testing out different numbers or asking for user inputs for the numbers array and targets. 👍🏾</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Coding Interview Prep – Free Resources to Help You Ace Your Interviews ]]>
                </title>
                <description>
                    <![CDATA[ By Evan SooHoo In the words of RealToughCandy, everyone wants a "one-stop shop" when it comes to learning. She uses this term to describe Educative.io, but Educative.io costs $60 a month unless you choose to commit to its annual plan. So it's not a f... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/coding-interview-preparation/</link>
                <guid isPermaLink="false">66d45edb73634435aafcef9e</guid>
                
                    <category>
                        <![CDATA[ algorithms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding ]]>
                    </category>
                
                    <category>
                        <![CDATA[ coding interview ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Interview tips ]]>
                    </category>
                
                    <category>
                        <![CDATA[ leetcode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 16 Nov 2021 23:50:43 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/11/thisisengineering-raeng-LxVzgYjkHp4-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Evan SooHoo</p>
<p>In the words of <a target="_blank" href="https://www.youtube.com/channel/UC54NcJvLCvM2CNaBjd5j6HA">RealToughCandy</a>, everyone wants a "one-stop shop" when it comes to learning.</p>
<p>She uses this term to describe <a target="_blank" href="https://www.educative.io/learn">Educative.io</a>, but Educative.io costs $60 a month unless you choose to commit to its annual plan. So it's not a free resource, which means it's not available to everyone.</p>
<p>If money were not a factor, you might buy a copy of <em>Cracking the Coding Interview</em>, get a LeetCode Premium subscription, and sign up for access to <a target="_blank" href="https://www.educative.io/courses/grokking-the-coding-interview">Grokking the Coding Interview</a> before scheduling some mock interviews. </p>
<p>Now, websites like LeetCode are interesting because they provide an excellent resource for free. A large percentage of LeetCode questions are free, the discussions section provides free solutions where the best code/explanations are voted to the top, and the platform itself can run hundreds of test cases in seconds.</p>
<p>Many people argue that <a target="_blank" href="https://www.youtube.com/watch?v=hhvvTD8SapI">LeetCode premium is not worth it</a>, though writers like Yangshun Tay beg to differ. What interests me about LeetCode is not their premium option, but that they make so much of their service available without it. </p>
<p>All that being said, there are a number of quality free resources you can use to prepare for your coding interviews. Let's go through my favorites now.</p>
<h2 id="heading-best-free-resources-for-coding-interview-prep">Best Free Resources for Coding Interview Prep</h2>
<p>Without further ado, here are the best free resources I have found for coding interview preparation:</p>
<h3 id="heading-freecodecamp-articles">freeCodeCamp articles</h3>
<p><a target="_blank" href="https://www.freecodecamp.org/news/coding-interviews-for-dummies-5e048933b82b/">The 30-minute guide to rocking your next coding interview</a> is a free article available on FreeCodeCamp. Half the value here is in curated lists of LeetCode questions to match every major topic</p>
<p>Here's <a target="_blank" href="https://www.freecodecamp.org/news/javascript-interview-prep-cheatsheet/">another great (and extensive) guide</a> that focuses on JavaScript interviews and goes through all the JS basics you'll need to know. It includes tons of code samples, and moves through the material in an approachable way.</p>
<h3 id="heading-cracking-the-coding-interview">Cracking the Coding Interview</h3>
<p><em>Cracking the Coding Interview</em> is still one of the best resources out there for interview prep, even in 2021. I have heard some people say that it is no longer sufficient, but I have had two coding interviews that were taken out of the book almost verbatim. </p>
<p>Unfortunately, this is not a free resource...but <a target="_blank" href="https://leetcode.com/discuss/general-discussion/1152824/cracking-the-coding-interview-6th-edition-in-leetcode">here is a LeetCode forum that maps every CTCI question to a LeetCode one</a>. </p>
<p>The reason this is acceptable is that they are not perfect mappings. For example, <a target="_blank" href="https://leetcode.com/problems/string-compression/">the LeetCode String Compression problem</a> is not exactly the same as its CTCI equivalent because it has an added constraint. It is actually <em>harder</em> than the CTCI version</p>
<p>If you do choose to purchase <em>Cracking the Coding Interview</em>, the solutions are all freely available on <a target="_blank" href="https://github.com/careercup/CtCI-6th-Edition">GitHub</a>. They are in multiple programming languages, in case you are not a Java developer. </p>
<p>McDowell herself built the repository and committed the Java portion to it, so it is very unlikely the repository will removed due to copyright infringement.</p>
<h3 id="heading-basecs">BaseCS</h3>
<p><a target="_blank" href="https://medium.com/basecs">BaseCS</a> is a great collection of articles that explain computer science fundamentals, from hash tables to sorting algorithms, with custom illustrations, well-written analogies, and light-hearted explanations. </p>
<p>Best of all, every single article is free from the Medium paywall. Had they not been, Joshi probably could have pocketed hundreds, if not thousands of dollars from all her readers.</p>
<h3 id="heading-educativeio">Educative.io</h3>
<p>The Educative.io course on 14 coding patterns is not free, but <a target="_blank" href="https://hackernoon.com/14-patterns-to-ace-any-coding-interview-question-c5bb3357f6ed">a summary</a> is available on HackerNoon and written by an Educative.io cofounder...presumably as either a gesture of goodwill, or a "free sample".</p>
<h3 id="heading-leetcode-questions-sorted-by-programming-pattern">LeetCode questions sorted by programming pattern</h3>
<p>Here is a public <a target="_blank" href="https://leetcode.com/discuss/career/448285/list-of-questions-sorted-by-common-patterns/453408">LeetCode post</a> that maps all 14 coding patterns to respective lists of LeetCode problems.</p>
<h3 id="heading-interviewnoodle-still-in-development">InterviewNoodle – still in development</h3>
<p>Arslan Ahmad is building a consolidated collection of interview preparation articles <a target="_blank" href="https://medium.com/interviewnoodle">on Medium</a> called InterviewNoodle. Just weeks ago, I would have written that this resource is very incomplete, but he has added so much content that I actually think he may now want to divide it into sections.  </p>
<p>This, like Educative.io, is meant to be a “one-stop shop.” That Arslan Ahmad is the founder of <a target="_blank" href="https://designgurus.org/course/grokking-the-system-design-interview?utm_source=google&amp;utm_medium=googAd&amp;utm_campaign=keyword_ad&amp;utm_id=goog1&amp;gclid=CjwKCAiAvriMBhAuEiwA8Cs5lQID0O_VM4qHE-espa4XePw22toAUEPvR2DKp1-s3Vnne9T19JBp1hoCp0sQAvD_BwE">Design Gurus</a> increased my respect for him exponentially, since this means he is attempting to build a free version of an Educative course that makes him money.  </p>
<p>Currently the Medium pages on this publication are not paywall blocked. This could be a coincidence, but for now it's a great resource.</p>
<p>The rest of this article will cover additional resources, though the ones above are my favorites.</p>
<h2 id="heading-additional-coding-interview-prep-resources">Additional Coding Interview Prep Resources</h2>
<h3 id="heading-an-interview-primer">An Interview Primer</h3>
<p>If you don't know what to expect in a coding interview, the "30-minute guide" from freeCodeCamp linked above is a great "primer". Still, it is rather lengthy – even though it takes 30 minutes to just read through it, it would take much longer to actually review and go through its "General tips" section.</p>
<p>This might be just what you're looking for if you want to be really thorough. But what other options do you have?</p>
<p>"Confessions from a Big Tech Hiring Manager" is my single favorite video. It's by "Pragmatic Engineer," and is all about the interview process. </p>
<p>This video has useful and practical advice, but it also conveys the perfect attitude. He argues that you should think of every failed interview as a learning opportunity.</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/vFOw_m5zNCs" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h3 id="heading-other-interview-prep-articles">Other Interview Prep articles</h3>
<p>"<a target="_blank" href="https://betterprogramming.pub/if-software-engineering-is-in-demand-why-is-it-so-hard-to-get-a-software-engineering-job-c043a964e463">If software engineering is in demand, why is it so hard to get a software engineering job?</a>" This is a tongue-in-cheek overview of the coding interview process. </p>
<p>If you read it, you should probably ignore the "string compression" story, which does not add much to the article.</p>
<p><a target="_blank" href="https://medium.com/interviewnoodle/the-other-side-of-the-software-engineer-interview-a8772edac0fc">The other side of the software engineer interview</a> is a kind of sequel to the article above, summarizing and responding to Pragmatic Engineer's thoughts.</p>
<p><a target="_blank" href="https://medium.com/illumination/the-responses-i-got-from-a-software-developer-candidate-that-made-me-hire-him-98ff8bf01298">The Responses I Got From A Software Developer Candidate That Made Me Hire Him</a> is an article that provides more insight on the interviewer's perspective, but unlike the two above it is behind Medium's paywall.</p>
<h2 id="heading-whats-the-interview-process-like-in-a-nutshell">What's the Interview Process Like, In a Nutshell?</h2>
<p>If I were asked to summarize all the resources above to you, here's what I would share:</p>
<ul>
<li>I would say that you typically get between 30 minutes to an hour to solve a coding question. </li>
<li>You typically get a choice of programming language like C++, Python, Java, or JavaScript, but not always...in some instances you do not have a choice.</li>
<li>Outside of the coding portion, they are free to ask you pretty much anything, from language-specific questions to favorite projects, but any interview with a coding portion tends to be dominated by it.</li>
</ul>
<p>And here's some general advice to consider: you are going to be dealing with people who may be pretty tired of interviews. Smile if you can. Try to show enthusiasm. Have a conversation, and try to talk to the interviewer the way you might communicate if the two of you were pair programming, but they were more senior.</p>
<h2 id="heading-how-to-start-your-interview-prep">How to Start Your Interview Prep</h2>
<p>I think that for most people starting out in this interview prep process, LeetCode is pretty hard. Here are two possible starting problems, though the best point of entry is admittedly <em>Cracking the Coding Interview.</em></p>
<ul>
<li><a target="_blank" href="https://leetcode.com/problems/fizz-buzz/">FizzBuzz on LeetCode</a>. I recommend it because it should not require any additional interview preparation, and will help you familiarize yourself with the LeetCode platform.</li>
<li><a target="_blank" href="https://medium.com/interviewnoodle/fizzbuzz-68fcdec8d2b2">Here's an article about FizzBuzz</a> on InterviewNoodle so you can learn more what that's about.</li>
<li><a target="_blank" href="https://leetcode.com/problems/jewels-and-stones/">Jewels and Stones on LeetCode</a>. If you are not able to solve this on your first try, then you will have to learn a technique that is useful in many coding interview problems.</li>
</ul>
<h3 id="heading-learn-about-hashmaps">Learn about hashmaps</h3>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/kVgy1GSDHG8" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p>There are many more data structures than just hashmaps, but I see these come up in coding interviews so often that I think they deserve their own section.</p>
<ul>
<li><a target="_blank" href="https://leetcode.com/problems/valid-anagram/">Valid Anagram</a> is another good LeetCode "starting point." It does not necessarily require a hashmap, but something that acts like a hashmap</li>
<li>Here is <a target="_blank" href="https://www.youtube.com/watch?v=IRN1VcA8CGc">Nick White solving Valid Anagram</a></li>
<li>This is <a target="_blank" href="https://www.youtube.com/watch?v=70qy6_gw1Hc">Alex Lee</a> using hashmaps in Java. He does not explain the internals of how they actually work, but he provides practical advice on how to actually use them.</li>
</ul>
<h3 id="heading-what-to-do-after-you-cover-the-basics">What to do after you cover the basics</h3>
<p>After you get started preparing and are comfortable with the basics, I would refer back to the resources above. </p>
<p>The 30-Minute Guide and <em>Cracking the Coding Interview</em> (again, there are free LeetCode problem mappings if you do not own <em>Cracking the Coding Interview)</em> both cover computer science fundamentals<em>.</em> And <em>14 coding patterns</em> goes a little bit further.</p>
<h2 id="heading-closing-thoughts">Closing Thoughts</h2>
<p>There is a lot more work to be done when it comes to coding interview preparation resources. It is relatively easy for me to simply point to good resources in an aggregate post, but actually providing comprehensive reviews or my own resource would require an order of magnitude more effort. I haven't gotten there yet.</p>
<p>So for now, there is certainly a gap. The most comprehensive content, in my opinion, can be found in <em>Cracking the Coding Interview</em> and this <a target="_blank" href="https://www.youtube.com/watch?v=70qy6_gw1Hc">Educative.io course</a>. And that's not to mention the plethora of resources someone with a lot of money could afford, from coaches, to coding interview bootcamps, to expensive mock interviews in which the interviewers provide detailed feedback. </p>
<p>That the people <em>behind</em> Educative.io and its "coding interview patterns" course have made efforts to provide free resources, like InterviewNoodle and a HackerNoon article, count for a lot to me.</p>
<p>I personally don't really use sites like GeeksforGeeks or interview resources on Github that are written exclusively in markdown. It would be very useful to build a platform with detailed blog-style explanations <em>and</em> embedded coding platforms, but at that point you would essentially be recreating Educative.io.</p>
<p>Medium provides an interesting case: Some of the best writers can be found here, but they are incentivized to put things behind a paywall. Anyone, in theory, can put up articles without a paywall on Medium the way BaseCS has. But few Medium writers seem to do this anymore.</p>
<p>We need <strong>more</strong> high-quality articles. We need practice problem lists that are continually updated. We need great YouTube content creators, like Nick White, to continue to provide clear problem explanations. </p>
<p>Efforts by BaseCS were largely successful, and my one wish is that it had continued to produce content...but this was all produced by a single person with a full-time job, a podcast, a YouTube channel, and apparently no compensation from Medium.</p>
<p>Not everyone has the same level of access to educational coding interview resources, so I admire the people who have done everything in their power to create free alternatives.</p>
<p>Yangshun Tay, author of "The 30-minute guide to rocking your next coding interview", sent me a personal email a few months after this article was published and shared some more helpful resources.</p>
<ul>
<li>Here's a link to the main <a target="_blank" href="https://www.techinterviewhandbook.org/">Tech Interview Handbook Website</a>, which contains in-depth and structured guides that can really help you prep for interviews. </li>
<li>Additionally, he's published <a target="_blank" href="https://www.techinterviewhandbook.org/grind75">Grind75</a> which generates study plans based on time left, which could also be of interest to your readers.</li>
</ul>
<p>The Tech Interview Handbook currently has about 69,000 stars on GitHub, and the website is the closest thing I have seen to a free, "one-stop-shop" software engineer interview resource.  </p>
<p>Grind75 is designed to be a better version of <a target="_blank" href="https://leetcode.com/discuss/general-discussion/460599/blind-75-leetcode-questions">Blind75</a>, a popular list Yangshun also made that received 3200 upvotes on a LeetCode discussion.</p>
<p>I hope these help you out! Happy prepping.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Coding Interview Backtracking Problems Crash Course – The Only One You'll Ever Need ]]>
                </title>
                <description>
                    <![CDATA[ Whether you are new to coding interviews or are already familiar with the concept of backtracking algorithms, this is the crash course for you. In it, we will learn about an all-purpose coding template for solving backtracking problems and apply it t... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/coding-interview-backtracking-problems-crash-course/</link>
                <guid isPermaLink="false">66d4601355db48792eed3f6b</guid>
                
                    <category>
                        <![CDATA[ coding interview ]]>
                    </category>
                
                    <category>
                        <![CDATA[ interview questions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Interview tips ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Job Interview ]]>
                    </category>
                
                    <category>
                        <![CDATA[ leetcode ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Lynn Zheng ]]>
                </dc:creator>
                <pubDate>Tue, 29 Jun 2021 20:00:32 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2021/06/1080P-Thumbnails-1-.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Whether you are new to coding interviews or are already familiar with the concept of <strong>backtracking</strong> algorithms, this is the crash course for you.</p>
<p>In it, we will learn about <strong>an all-purpose coding template</strong> for solving backtracking problems and apply it to <strong>two LeetCode hard problems</strong>. Ready to crunch your next coding interview? Let's go!</p>
<p>If you just want to dive right in, <a target="_blank" href="https://www.youtube.com/watch?v=H2gnD7Ixeao">you can find the course here</a> (and linked at the bottom of this article). If you want a little more info, read on. :)</p>
<h2 id="heading-who-is-the-course-for-and-what-is-the-backtracking-algorithm">Who is the Course for and What is the Backtracking Algorithm?</h2>
<p>This course is suitable for anyone who is preparing for coding interviews, especially those who are looking to hone their skills in solving <strong>backtracking</strong> problems.</p>
<p>Backtracking is a common category for questions in coding interviews. The algorithm for solving those problems usually involves <strong>recursion</strong> and <strong>building incrementally on previous states</strong> to arrive at the ultimate valid solution.</p>
<p>Backtracking is a favorite topic among top tech companies like Google, Microsoft, and Facebook, precisely because it requires robust reasoning and coding competence to nail those questions.</p>
<p>However, because of its recursive nature and complex problem definition, backtracking problems are usually a major source of confusion among devs who are preparing for coding interviews.</p>
<p>To address this confusion, this crash course aims to arm with you a concise, 20-line template that you can apply to the majority of backtracking problems.</p>
<h2 id="heading-course-outline">Course Outline</h2>
<p>This course runs for a total of 40 minutes and the structure is as follows:</p>
<ul>
<li><p>An 8-minute introduction to <a target="_blank" href="https://gist.github.com/RuolinZheng08/cdd880ee748e27ed28e0be3916f56fa6">the template</a></p>
</li>
<li><p>A 15-minute hands-on code-along session for <a target="_blank" href="https://leetcode.com/problems/n-queens/">LeetCode Question 51. N-Queens</a></p>
</li>
<li><p>A 15-minute hands-on code-along session for <a target="_blank" href="https://leetcode.com/problems/sudoku-solver/">LeetCode Question 37. Sudoku Solver</a></p>
</li>
</ul>
<h2 id="heading-the-all-purpose-template">The All-Purpose Template</h2>
<p>For your convenience, I've copied the template over. This is exactly the same template that I use for my coding interviews, or when I'm developing algorithms for my indie games. I even used it once in my research on a non-convex optimization problem.</p>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">is_valid_state</span>(<span class="hljs-params">state</span>):</span>
    <span class="hljs-comment"># check if it is a valid solution</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_candidates</span>(<span class="hljs-params">state</span>):</span>
    <span class="hljs-keyword">return</span> []

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">search</span>(<span class="hljs-params">state, solutions</span>):</span>
    <span class="hljs-keyword">if</span> is_valid_state(state):
        solutions.append(state.copy())
        <span class="hljs-comment"># return</span>

    <span class="hljs-keyword">for</span> candidate <span class="hljs-keyword">in</span> get_candidates(state):
        state.add(candidate)
        search(state, solutions)
        state.remove(candidate)

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">solve</span>():</span>
    solutions = []
    state = set()
    search(state, solutions)
    <span class="hljs-keyword">return</span> solutions
</code></pre>
<p>The first three are all helper functions, and the last and most important one, <code>solve</code>, is essentially the one that a LeetCode problem is asking you to write.</p>
<h2 id="heading-solving-leetcode-problems-hands-on">Solving LeetCode Problems Hands-On</h2>
<p>We will next apply this template to solving two LeetCode hard problems: <a target="_blank" href="https://leetcode.com/problems/n-queens/">LeetCode Question 51. N-Queens</a> and <a target="_blank" href="https://leetcode.com/problems/sudoku-solver/">LeetCode Question 37. Sudoku Solver</a>.</p>
<p>To illustrate the flexibility of the template, see below for how we solve the N-Queens problem by doing nothing fancy other than adapting the four functions (renaming <code>solve</code> to <code>solveNQueens</code>). The complete code for either problem is available <a target="_blank" href="https://gist.github.com/RuolinZheng08/cdd880ee748e27ed28e0be3916f56fa6">in my GitHub gist</a>.</p>
<p>Watch <a target="_blank" href="https://youtu.be/H2gnD7Ixeao">the video course</a> to follow along my analysis and adaptation of the template.</p>
<pre><code class="lang-python"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Solution</span>:</span>
    <span class="hljs-comment"># solveNQueens is essentially the solve function</span>
    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">solveNQueens</span>(<span class="hljs-params">self, n: int</span>) -&gt; List[List[str]]:</span>
        solutions = []
        state = []
        self.search(state, solutions, n)
        <span class="hljs-keyword">return</span> solutions

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">is_valid_state</span>(<span class="hljs-params">self, state, n</span>):</span>
        <span class="hljs-comment"># check if it is a valid solution</span>
        <span class="hljs-keyword">return</span> len(state) == n

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_candidates</span>(<span class="hljs-params">self, state, n</span>):</span>
        <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> state:
            <span class="hljs-keyword">return</span> range(n)

        <span class="hljs-comment"># find the next position in the state to populate</span>
        position = len(state)
        candidates = set(range(n))
        <span class="hljs-comment"># prune down candidates that place the queen into attacks</span>
        <span class="hljs-keyword">for</span> row, col <span class="hljs-keyword">in</span> enumerate(state):
            <span class="hljs-comment"># discard the column index if it's occupied by a queen</span>
            candidates.discard(col)
            dist = position - row
            <span class="hljs-comment"># discard diagonals</span>
            candidates.discard(col + dist)
            candidates.discard(col - dist)
        <span class="hljs-keyword">return</span> candidates

    <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">search</span>(<span class="hljs-params">self, state, solutions, n</span>):</span>
        <span class="hljs-keyword">if</span> self.is_valid_state(state, n):
            state_string = self.state_to_string(state, n)
            solutions.append(state_string)
            <span class="hljs-keyword">return</span>

        <span class="hljs-keyword">for</span> candidate <span class="hljs-keyword">in</span> self.get_candidates(state, n):
            <span class="hljs-comment"># recurse</span>
            state.append(candidate)
            self.search(state, solutions, n)
            state.pop()
</code></pre>
<p>Check out the video course here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/H2gnD7Ixeao" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<p> </p>
<p>You can access the template as well as the solutions to the two LeetCode problems (<strong>N-Queens</strong> and <strong>Sudoku Solver</strong>) in my GitHub gist:</p>
<div class="gist-block embed-wrapper" data-gist-show-loading="false" data-id="cdd880ee748e27ed28e0be3916f56fa6">
        <script src="https://gist.github.com/RuolinZheng08/cdd880ee748e27ed28e0be3916f56fa6.js"></script></div><p> </p>
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>Remember that practice makes perfect, so do try applying this template to <a target="_blank" href="https://leetcode.com/tag/backtracking/">more backtracking problems on LeetCode.</a> Best of luck crunching your next coding interview!</p>
<p>For more content like this, check out my YouTube channel:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/undefined" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Solve Leetcode Problems With Python One-Liners ]]>
                </title>
                <description>
                    <![CDATA[ By Ganesh Kumar Marimuthu Python is one of the most powerful programming languages. It gives us various unique features and functionalities that make it easy for us to write code.  In this article we'll solve Leetcode array problems in one line using... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/solve-leetcode-problems-using-python-list-comprehension/</link>
                <guid isPermaLink="false">66d45edbb3016bf139028d2f</guid>
                
                    <category>
                        <![CDATA[ leetcode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Problem Solving ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 02 Apr 2021 15:13:35 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/60640fde9618b008528aa027.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ganesh Kumar Marimuthu</p>
<p>Python is one of the most powerful programming languages. It gives us various unique features and functionalities that make it easy for us to write code. </p>
<p>In this article we'll solve Leetcode array problems in one line using one of Python's most interesting features – <strong>List Comprehension</strong>.</p>
<h2 id="heading-what-is-list-comprehension">What is List Comprehension?</h2>
<p>Before going into the problems, let's make sure we understand what list comprehension is all about.</p>
<blockquote>
<p>A list comprehension is a syntactic construct available in some programming languages for creating a list based on existing lists  </p>
<ul>
<li>Wikipedia</li>
</ul>
</blockquote>
<p>Let's see how list comprehension works with an example.</p>
<p>Consider an array of numbers. Our task is to add 1 to the numbers at odd indices and to add 2 to the number at even indices.</p>
<p>Now we'll see how to solve the above problem using both a for-loop and list comprehension.</p>
<h3 id="heading-how-to-solve-the-problem-with-a-for-loop">How to solve the problem with a for-loop</h3>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">addOneAndTwo</span>(<span class="hljs-params">nums, n</span>):</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(n):
        <span class="hljs-keyword">if</span> i % <span class="hljs-number">2</span> == <span class="hljs-number">1</span>:
            nums[i] += <span class="hljs-number">1</span> 
        <span class="hljs-keyword">else</span>:
            nums[i] += <span class="hljs-number">2</span> 
    <span class="hljs-keyword">return</span> nums
</code></pre>
<h3 id="heading-how-to-solve-it-with-list-comprehension">How to solve it with list comprehension</h3>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">addOneAndTwo</span>(<span class="hljs-params">nums, n</span>):</span>
    <span class="hljs-keyword">return</span> [nums[i] + <span class="hljs-number">1</span> <span class="hljs-keyword">if</span> i % <span class="hljs-number">2</span> == <span class="hljs-number">1</span> <span class="hljs-keyword">else</span> nums[i] + <span class="hljs-number">2</span> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(n)]
</code></pre>
<p>You can see how the solution using list comprehension is simplified from 6 lines to 1 line. This is the power of list comprehension.</p>
<h2 id="heading-how-to-solve-leetcode-problems-with-list-comprehension">How to Solve Leetcode Problems with List Comprehension</h2>
<p>Now let us solve the below Leetcode problems in 1 line using list comprehension.</p>
<h3 id="heading-1-shuffle-the-arrayhttpsleetcodecomproblemsshuffle-the-array">1. <a target="_blank" href="https://leetcode.com/problems/shuffle-the-array/">Shuffle The Array</a></h3>
<p>Here's the problem from Leetcode:</p>
<p>Given the array <code>nums</code> consisting of <code>2n</code> elements in the form <code>[x&lt;sub&gt;1&lt;/sub&gt;,x&lt;sub&gt;2&lt;/sub&gt;,...,x&lt;sub&gt;n&lt;/sub&gt;,y&lt;sub&gt;1&lt;/sub&gt;,y&lt;sub&gt;2&lt;/sub&gt;,...,y&lt;sub&gt;n&lt;/sub&gt;]</code>. <em>Return the array in the form</em> <code>[x&lt;sub&gt;1&lt;/sub&gt;,y&lt;sub&gt;1&lt;/sub&gt;,x&lt;sub&gt;2&lt;/sub&gt;,y&lt;sub&gt;2&lt;/sub&gt;,...,x&lt;sub&gt;n&lt;/sub&gt;,y&lt;sub&gt;n&lt;/sub&gt;]</code>.</p>
<h4 id="heading-example">Example</h4>
<p>Input: nums = [2,5,1,3,4,7], n = 3<br>Output: [2,3,5,4,1,7] </p>
<p>Explanation: Since x1=2, x2=5, x3=1, y1=3, y2=4, y3=7 then the answer is [2,3,5,4,1,7].</p>
<h4 id="heading-solution">Solution</h4>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">shuffle</span>(<span class="hljs-params">self, nums, n</span>):</span>
    <span class="hljs-keyword">return</span> reduce(<span class="hljs-keyword">lambda</span> a, b: a + b, [[nums[i], nums[j]] <span class="hljs-keyword">for</span> i, j <span class="hljs-keyword">in</span> zip(range(<span class="hljs-number">0</span>, n), range(n, <span class="hljs-number">2</span> * n))])
</code></pre>
<h3 id="heading-2-number-of-good-pairshttpsleetcodecomproblemsnumber-of-good-pairs">2. <a target="_blank" href="https://leetcode.com/problems/number-of-good-pairs/">Number of Good Pairs</a></h3>
<p>Given an array of integers <code>nums</code>. A pair <code>(i,j)</code> is called <em>good</em> if <code>nums[i]</code> == <code>nums[j]</code> and <code>i</code> &lt; <code>j</code>.Return the number of <em>good</em> pairs.</p>
<h4 id="heading-example-1">Example</h4>
<p>Input: nums = [1,2,3,1,1,3]<br>Output: 4 </p>
<p>Explanation: There are 4 good pairs (0,3), (0,4), (3,4), (2,5) 0-indexed.</p>
<h4 id="heading-solution-1">Solution</h4>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">numIdenticalPairs</span>(<span class="hljs-params">self, nums</span>):</span>
    <span class="hljs-keyword">return</span> sum([int(i != j <span class="hljs-keyword">and</span> nums[i] == nums[j]) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">0</span>, len(nums)) <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> range(i + <span class="hljs-number">1</span>, len(nums))])
</code></pre>
<h3 id="heading-3-kids-with-the-greatest-number-of-candieshttpsleetcodecomproblemskids-with-the-greatest-number-of-candies">3. <a target="_blank" href="https://leetcode.com/problems/kids-with-the-greatest-number-of-candies/">Kids With the Greatest Number of Candies</a></h3>
<p>Given the array <code>candies</code> and the integer <code>extraCandies</code>, where <code>candies[i]</code> represents the number of candies that the <strong><em>ith</em></strong> kid has.</p>
<p>For each kid check if there is a way to distribute <code>extraCandies</code> among the kids such that they can have the <strong>greatest</strong> number of candies among them. Notice that multiple kids can have the <strong>greatest</strong> number of candies.</p>
<h4 id="heading-example-2">Example</h4>
<p>Input: candies = [2,3,5,1,3], extraCandies = 3<br>Output: [true,true,true,false,true]</p>
<p>Explanation: Kid 1 has 2 candies, and if they receive all extra candies (3) they will have 5 candies – the greatest number of candies among the kids. </p>
<p>Kid 2 has 3 candies, and if they receive at least 2 extra candies then they will have the greatest number of candies among the kids. </p>
<p>Kid 3 has 5 candies, and this is already the greatest number of candies among the kids. </p>
<p>Kid 4 has 1 candy, and even if they receive all extra candies they will only have 4 candies. </p>
<p>Kid 5 has 3 candies, and if they receive at least 2 extra candies then they will have the greatest number of candies among the kids.</p>
<h4 id="heading-solution-2">Solution</h4>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">kidsWithCandies</span>(<span class="hljs-params">self, candies, extraCandies</span>):</span>
    <span class="hljs-keyword">return</span> [candy + extraCandies &gt;= max(candies) <span class="hljs-keyword">for</span> candy <span class="hljs-keyword">in</span> candies]
</code></pre>
<h3 id="heading-4-decompress-run-length-encoded-listhttpsleetcodecomproblemsdecompress-run-length-encoded-list">4. <a target="_blank" href="https://leetcode.com/problems/decompress-run-length-encoded-list/">Decompress Run-Length Encoded List</a></h3>
<p>We are given a list <code>nums</code> of integers representing a list compressed with run-length encoding.</p>
<p>Consider each adjacent pair of elements <code>[freq, val] = [nums[2*i], nums[2*i+1]]</code> (with <code>i &gt;= 0</code>).  For each such pair, there are <code>freq</code> elements with value <code>val</code> concatenated in a sublist. Concatenate all the sublists from left to right to generate the decompressed list.</p>
<p>Return the decompressed list.</p>
<h4 id="heading-example-3">Example</h4>
<p>Input: nums = [1,2,3,4]<br>Output: [2,4,4,4] </p>
<p>Explanation: The first pair [1,2] means we have freq = 1 and val = 2 so we generate the array [2]. </p>
<p>The second pair [3,4] means we have freq = 3 and val = 4 so we generate [4,4,4]. At the end the concatenation [2] + [4,4,4] is [2,4,4,4].</p>
<h4 id="heading-solution-3">Solution</h4>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">decompressRLElist</span>(<span class="hljs-params">self, nums</span>):</span>
    <span class="hljs-keyword">return</span> reduce(<span class="hljs-keyword">lambda</span> a, b: a + b, [[nums[i + <span class="hljs-number">1</span>]] * nums[i] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">0</span>, len(nums), <span class="hljs-number">2</span>)])
</code></pre>
<h3 id="heading-5-richest-customers-wealthhttpsleetcodecomproblemsrichest-customer-wealth">5. <a target="_blank" href="https://leetcode.com/problems/richest-customer-wealth/">Richest Customer's Wealth</a></h3>
<p>You are given an <code>m x n</code> integer grid <code>accounts</code> where <code>accounts[i][j]</code> is the amount of money the <code>i​​​​​&lt;sup&gt;​​​​​​th&lt;/sup&gt;​​​​</code> customer has in the <code>j​​​​​&lt;sup&gt;​​​​​​th&lt;/sup&gt;</code>​​​​ bank. Return <em>the <strong>wealth</strong> that the richest customer has.</em></p>
<p>A customer's <strong>wealth</strong> is the amount of money they have in all their bank accounts. The richest customer is the customer that has the maximum <strong>wealth</strong>.</p>
<h4 id="heading-example-4">Example</h4>
<p>Input: accounts = [[1,2,3],[3,2,1]]<br>Output: 6 </p>
<p>Explanation: <code>1st customer has wealth = 1 + 2 + 3 = 6 2nd customer has wealth = 3 + 2 + 1 = 6</code>  Both customers are considered the richest with a wealth of 6 each, so return 6.</p>
<h4 id="heading-solution-4">Solution</h4>
<pre><code class="lang-python"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">maximumWealth</span>(<span class="hljs-params">self, accounts</span>):</span>
    <span class="hljs-keyword">return</span> max([sum(row) <span class="hljs-keyword">for</span> row <span class="hljs-keyword">in</span> accounts])
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>I hope the above solutions were useful. You can combine <a target="_blank" href="https://data-flair.training/blogs/python-list-comprehension/"><strong>list comprehension</strong></a> with other functions like <a target="_blank" href="https://www.freecodecamp.org/news/15-useful-javascript-examples-of-map-reduce-and-filter-74cbbb5e0a1f/"><strong>map</strong>, <strong>filter</strong> and <strong>reduce</strong></a> to make the solutions more simple and effective.</p>
<h2 id="heading-thank-you">Thank You 🤘</h2>
<p><a target="_blank" href="https://www.linkedin.com/in/ganeshkumarm1">Linkedin</a> | <a target="_blank" href="https://github.com/ganeshkumarm1">Github</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Unmasking Bitmasked Dynamic Programming ]]>
                </title>
                <description>
                    <![CDATA[ By Sachin Malhotra How to go from Fearing it to Conquering it! There are no coincidences in this world. — Grand Master Oogway Well, Master Oogway, no disrespect, coincidences do occur and I think they are just God’s way of remaining anonymous. Not... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/unmasking-bitmasked-dynamic-programming-25669312b77b/</link>
                <guid isPermaLink="false">66c3641a1a1cf73cbc81f158</guid>
                
                    <category>
                        <![CDATA[ algorithms ]]>
                    </category>
                
                    <category>
                        <![CDATA[ leetcode ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Python ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 03 Jan 2019 16:38:18 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*h4NHSLyn2d1I1hNTCsYDhw.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Sachin Malhotra</p>
<h4 id="heading-how-to-go-from-fearing-it-to-conquering-it">How to go from Fearing it to Conquering it!</h4>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*h4NHSLyn2d1I1hNTCsYDhw.png" alt="Image" width="800" height="800" loading="lazy"></p>
<blockquote>
<p>There are no coincidences in this world.</p>
<p><strong>— Grand Master Oogway</strong></p>
</blockquote>
<p>Well, Master Oogway, no disrespect, coincidences do occur and I think they are just God’s way of remaining anonymous. Not just me, Albert Einstein believes this too ?.</p>
<p>111, that’s not really my <em>lucky number,</em> so to say.</p>
<p>However, this number filled me with joy and ecstasy when I saw it as my rank on the rankings page of the <a target="_blank" href="https://leetcode.com/contest/weekly-contest-111">LeetCode</a> contest number 111.</p>
<p>What a coincidence!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Lhw6zJiM5sZwaQ7Z7VlOLQ.png" alt="Image" width="800" height="425" loading="lazy"></p>
<p>That’s the highest ranking in a weekly contest that I’ve achieved so far on the platform. The contest number and the ranking were obviously pure coincidence.</p>
<p>The contest usually consists of an Easy problem, 2 Medium level problems, and a Hard problem.</p>
<p>More often than not, the hard problem is something that requires a lot of algorithmic knowledge and prior practice to be able to pull off during the contest. This contest’s final problem was no exception to this.</p>
<p>Why do I say it was very hard? Have a look at the number of people who were able to solve it during the contest.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*YLg5aPTagh8k4L9M9FkVOw.png" alt="Image" width="481" height="496" loading="lazy"></p>
<p>As the title of the article suggests, this problem was to be solved using Bit Masking based Dynamic Programming.</p>
<p><em>Dynamic Programming</em> is one of the most dreaded algorithmic domains out there. It requires a lot of practice to develop intuition about a dynamic programming-based solution to a problem. I’ve always considered it to be an enhancement to a recursive solution to a problem. The main idea behind dynamic programming in layperson’s terms is:</p>
<blockquote>
<p>Avoid repeated computations by caching the results.</p>
</blockquote>
<p><em>Bitmasking</em> as a topic in computer programming is something that I have (and I’m sure countless of other developers out there have as well) feared for a long time. This is one of those topics that will surely take you off balance in an interview and get you a rejection.</p>
<p>Programmers out there generally tend to avoid practicing problems related to this topic simply because it is difficult to build an intuition about it.</p>
<p>Optimizations related to bit manipulations occur in the most unexpected of places. With some practice, I have been able to overcome the <em>fear,</em> so to say, of working on bitmasking-based programming problems.</p>
<p>In this article, apart from describing the solution to the problem I’ve mentioned above, in detail, I will also go over some basics of bitmasking and some programming problems where it can come in handy.</p>
<p>As with any new thing you learn, it’s very difficult to retain theoretical concepts related to bitmasking. Retention is the best when it comes via practice. That is the main aim of this article. Let’s quickly look at the table of contents before we kick off the main article.</p>
<h3 id="heading-get-a-bit-of-hot-chocolate-and-be-ready-for">Get a <em>bit</em> of Hot Chocolate and be ready for …</h3>
<ul>
<li><a target="_blank" href="https://medium.com/p/25669312b77b#ea86">0️⃣ 1️⃣ What is Bit Manipulation? 0️⃣ 1️⃣</a></li>
<li><a target="_blank" href="https://medium.com/p/25669312b77b#ee57">The Basics ✍️</a></li>
<li><a target="_blank" href="https://medium.com/p/25669312b77b#c94f">Counting the Number of set bits</a></li>
<li><a target="_blank" href="https://medium.com/p/25669312b77b#245e">Masking and Unmasking a specific bit</a></li>
<li><a target="_blank" href="https://medium.com/p/25669312b77b#927e">? Missing Number ?</a></li>
<li><a target="_blank" href="https://medium.com/p/25669312b77b#14da">☝️?✌️? Counting Bits ?? ??</a></li>
<li><a target="_blank" href="https://medium.com/p/25669312b77b#e86c">⛩ Maximum Product of Word Lengths ⛩</a></li>
<li><a target="_blank" href="https://medium.com/p/25669312b77b#a050">Set Representation using Bitmasking</a></li>
<li><a target="_blank" href="https://medium.com/p/25669312b77b#a510">??Partition Array to K Equal Sum Subsets ??</a></li>
<li><a target="_blank" href="https://medium.com/p/25669312b77b#1c4c">? Find the Shortest Superstring ?</a></li>
<li><a target="_blank" href="https://medium.com/p/25669312b77b#322f">Conclusion ??</a></li>
<li><a target="_blank" href="https://medium.com/p/25669312b77b#0017">References ?</a></li>
</ul>
<h3 id="heading-0-1-what-is-bit-manipulation-0-1">0️⃣ 1️⃣ What is Bit Manipulation? 0️⃣ 1️⃣</h3>
<blockquote>
<p>A bit is to the computing world what an atom is to human life.</p>
</blockquote>
<p>A bit is essentially the smallest unit of storage in a computer. It’s the only unit that a computer understands.</p>
<p>The only information that a bit can store is formed from two different states: 0️⃣ and 1️⃣. Any sort of computation that a computer performs is basically some form of bit manipulation.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*7BiK3Ininix3obYJgNXSJA.png" alt="Image" width="800" height="1005" loading="lazy"></p>
<p>Let’s look at a <a target="_blank" href="https://en.wikipedia.org/wiki/Bit_manipulation"><em>Wikipedia</em></a> definition for bit manipulation:</p>
<blockquote>
<p>Bit manipulation is the act of algorithmically manipulating bits or other pieces of data shorter than a word. Computer programming tasks that require bit manipulation include low-level device control, error detection and correction algorithms, data compression, encryption algorithms, and optimization. For most other tasks, modern programming languages allow the programmer to work directly with abstractions instead of bits that represent those abstractions.</p>
</blockquote>
<p>Implementation-wise, one of the most useful and effective low-level optimizations to an algorithm is bit manipulation.</p>
<p>In some cases, bit manipulation can bypass looping over a data structure and give manifolds speed improvement. The only downfall to such optimizations is the code readability and maintenance.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*S9DTvKGpg1JcOF15XYAATQ.png" alt="Image" width="800" height="377" loading="lazy">
<em>Who wrote this piece of shitty (read lightning fast) code?</em></p>
<p>That is one scary piece of ☠<a target="_blank" href="https://medium.freecodecamp.org/lets-backtrack-and-save-some-queens-1f9ef6af5415">code</a> ☠</p>
<h3 id="heading-the-basics">The Basics ✍️</h3>
<p>At the heart of bit manipulation are the bit-wise operators:</p>
<ul>
<li>And (&amp;)</li>
<li>Or (|)</li>
<li>Not (~)</li>
<li>XOR (^)</li>
</ul>
<p>These are the fundamental operators using which we can perform some complicated bit manipulation operations. Hence, it’s very important to brush up on these operators and their truth tables before moving onto some more interesting stuff.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*deg14AeGo8SQWq8uwCVZmQ.png" alt="Image" width="800" height="175" loading="lazy">
_Source: [https://www.topcoder.com](https://www.topcoder.com" rel="noopener" target="<em>blank" title=")</em></p>
<p>The truth tables show the results for these operators when they operate on 2 bits represented by <code>A</code> and <code>B</code>. The computer has to deal with much more than just one bit of data.</p>
<p>The data processed by the system is generally in bytes or kilobytes or more. How do these operators work on operands represented by for e.g. 8-bits or 16-bits? In such a scenario, the operations are the same, except that they operate on each bit of the arguments. Let’s consider a simple example to clarify this.</p>
<pre><code>A = <span class="hljs-number">11101010</span>B = <span class="hljs-number">00110101</span>
</code></pre><pre><code>+-+-+-+-  AND  -+-+-+-+A &amp; B = <span class="hljs-number">00100000</span>
</code></pre><pre><code>+-+-+-+-  OR   -+-+-+-+A | B = <span class="hljs-number">11111111</span>
</code></pre><pre><code>+-+-+-+-  NOT  -+-+-+-+~A    = <span class="hljs-number">00010101</span>
</code></pre><pre><code>+-+-+-+-  XOR  -+-+-+-+A ^ B = <span class="hljs-number">11011111</span>
</code></pre><p>In addition to these 4 basic operators, there are two other set of bitwise operators that do come in very handy. Almost all the problems that we will look at in this article will be making use of them to give a huge boost in computational speed. These are the left shift <code>&amp;l</code>t;&lt; and the right <code>sh</code>ift &gt;&gt; operators.</p>
<p>Simply speaking, the left shift operator means multiplying a number by 2 and the right shift operator means dividing a number by 2.</p>
<p>Let’s look at a simple animation to show why these operators are called <code>left shift</code> and <code>right shift</code> respectively.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*GtkdWOFKMEGrzvYzsK9pZg.gif" alt="Image" width="800" height="281" loading="lazy">
<em>Left Shift Operation in Action.</em></p>
<p>For demonstrating the left shift operation, we start off with the decimal number <code>1</code> and then repeatedly multiply it with 2. As you can see in the binary representation of the resulting numbers, the only <code>1</code> in the representation keeps on shifting left one step at a time. That’s why it’s called the <em>left</em> shift operation.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*EM9AEq3brodEgJRL-annkQ.gif" alt="Image" width="800" height="281" loading="lazy">
<em>Right Shift Operation in Action.</em></p>
<p>Along the same lines, for demonstrating the right shift operation, we start off with the decimal number <code>128</code>and then repeatedly divide it by 2. As you can see in the binary representation of the resulting numbers, the only <code>1</code> in the representation keeps on shifting right one step at a time. That’s why it’s called the <em>right</em> shift operation.</p>
<p>Now that we are all versed with the basic binary operators, let’s move on to some simple use cases for these operators. We will look at a few examples below. These are not programming problems by themselves, however, they are used a lot as building blocks in a lot of algorithms.</p>
<h3 id="heading-basic-use-cases">Basic Use Cases ?</h3>
<h4 id="heading-counting-the-number-of-set-bits">Counting the Number of set bits</h4>
<p>One of the basic utilities for the operators we looked at above is to count the number of bits, set in a given binary representation.</p>
<p>This might not seem an important use case right now, but we will be getting into more details later on and then it will start to seem more meaningful. For now, let’s just count the number of set bits as efficiently as possible.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*dcghg6rp6ycXUFxBJI1oFA.gif" alt="Image" width="480" height="341" loading="lazy">
_Source: [giphy](https://giphy.com/gifs/cRMgB2wjHhVN2tDD2z" rel="noopener" target="<em>blank" title=")</em></p>
<p>The first method that we will look at for this, is a <em>bit</em> intuitive. It makes use of the bitwise <code>AND</code> operator. Starting from the least significant bit, we simply check if the bit at each position is set or not and increment a counter accordingly.</p>
<p>The AND operator returns <code>True</code> iff both the bits are <code>True</code>. Let’s look at the code for this.</p>
<p>Yet another way of doing this is by <code>ANDing</code> the number with <code>itself-1</code> until the number becomes zero. The number of steps taken to reach 0 will be the number of set bits in the original number.</p>
<p>The reason this works is that every time we <code>AND</code> the number with <code>itself-1</code>, one bit gets removed from the number. This goes on until the number becomes zero.</p>
<h4 id="heading-masking-and-unmasking-a-specific-bit">Masking and Unmasking a specific bit</h4>
<p>Suppose we want to <em>mask a specific</em> bit in a binary representation<em>.</em> This simply means turning off the bit or transforming a <code>1 → 0</code> . On similar lines, <em>unmasking</em> simply means the reverse operation on a specific bit.</p>
<p>You might be wondering why this is useful at all. One of the most important use cases for masking (or unmasking) a bit is in set related operations.</p>
<p>We can represent a set of items as an <code>X-bit</code> integer, <code>X</code>is the number of items in the set. Masking a bit would mean the removal of that item from the set. For a practical application of this, be patient and read on ?.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*j9hCDIKxF8t6tBelC2y0og.gif" alt="Image" width="700" height="379" loading="lazy">
_Source: [giphy](https://giphy.com/gifs/k-kindergarten-behTrfrYhb3iw" rel="noopener" target="<em>blank" title=")</em></p>
<p>XOR is a very versatile operator and it is perfect for the task of masking and unmasking operations.</p>
<pre><code><span class="hljs-number">1</span> ^ ? → <span class="hljs-number">00</span> ^ ? → <span class="hljs-number">1</span>
</code></pre><blockquote>
<p>XOR outputs 1 when both the bits are opposite and a 0 when both the bits are the same.</p>
</blockquote>
<p>Essentially, we can make use of the same <em>masking</em> variable for achieving the set / un-set operation corresponding to a particular bit (the integer in the ? is being called the masking variable).</p>
<pre><code>A ^ (<span class="hljs-number">1</span> &lt;&lt; i)
</code></pre><p>The above operation will lead to masking the bit at index <code>i</code> if originally that bit was <em>set</em> in <code>A</code> and the same operation will lead to unmasking the bit at index <code>i</code> if originally it was <em>unset</em> in <code>A</code>.</p>
<p>We have already seen how to detect if a bit is set or not when we looked at ways to count the number of set bits in a given binary representation.</p>
<p>An important thing to note here is the index. Usually, for data structures in high-level programming languages, whenever we refer to a specific index, we mean the index of a particular element in that data-structure starting from the left end.</p>
<p>What we are referring to an index above is from the <em>right</em> end (the least significant bit in the binary representation has the index 0).</p>
<p>That’s more than enough of the basics for now. Let’s get to some actual programming problems. This will help solidify what we’ve learned so far in the article and also help build up an intuition for solving problems using bit manipulation in general.</p>
<h3 id="heading-missing-number">? Missing Number ?</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*29-nQPqWtIGG8enJCzhtiA.png" alt="Image" width="800" height="398" loading="lazy">
_Source: [LeetCode](https://leetcode.com/problems/missing-number/description/" rel="noopener" target="<em>blank" title=")</em></p>
<p>There are multiple ways of solving this problem. We can sort the given list of numbers and then iterate from <code>0..n</code> and easily find the missing number. This will give us a <code>O(NlogN)</code> solution.</p>
<p>Another way of solving this problem is by making use of a dictionary. We simply add all the elements in our list to a dictionary and then we can simply search for the missing number. This is a linear time solution but it makes use of additional space.</p>
<p>Let’s look at how we can achieve a <code>O(1)</code> space, <code>O(N)</code> time solution like a boss ? by using bit manipulation.</p>
<p>We will make use the <code>XOR</code> property here to solve this problem. As mentioned before, XOR evaluates to <code>True</code> when the input bits are different and it evaluates to <code>False</code> when presented with the same bits. We are interested in the later scenario. What do you think the following evaluates to?</p>
<pre><code>A ^ A
</code></pre><p><img src="https://cdn-media-1.freecodecamp.org/images/1*GOxqtc8ix6rJToOxHdi24Q.gif" alt="Image" width="498" height="325" loading="lazy">
_Source: [tenor](https://tenor.com/view/bottaro-zero-nothing-trani-ok-gif-12693830" rel="noopener" target="<em>blank" title=")</em></p>
<p><code>XORing</code> a number with itself gives us 0. That’s the main idea behind our approach here.</p>
<p>So, what we will do is, we will XOR all the numbers in our list. Let’s call the value we get after this as <code>A</code> .</p>
<p>We will XOR all the numbers from <code>0..n</code> together. Let’s call this value, <code>B</code>.</p>
<p>By doing this, all the numbers present in the original array will get XORed to their counterparts and will evaluate to 0. The only number left in the end will be the missing number.</p>
<pre><code>A ^ B = missing number
</code></pre><h3 id="heading-counting-bits">☝️?✌️? Counting Bits ?? ??</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*z3uANN-CgpBiY5QBoBxtJQ.png" alt="Image" width="800" height="482" loading="lazy">
_Source: [LeetCode](https://leetcode.com/problems/counting-bits/description/" rel="noopener" target="<em>blank" title=")</em></p>
<p>This is one of those problems where writing down the answer for various test cases and observing the results for patterns really helps. So, we will do exactly that and use the pattern we find to directly arrive at the final algorithm.</p>
<p>Let’s look at the number of 1’s in the binary representation of the first 16 numbers.</p>
<pre><code><span class="hljs-number">0</span>  <span class="hljs-number">1</span>  <span class="hljs-number">2</span>  <span class="hljs-number">3</span>  <span class="hljs-number">4</span>  <span class="hljs-number">5</span>  <span class="hljs-number">6</span>  <span class="hljs-number">7</span>  <span class="hljs-number">8</span>  <span class="hljs-number">9</span>  <span class="hljs-number">10</span>  <span class="hljs-number">11</span>  <span class="hljs-number">12</span>  <span class="hljs-number">13</span>  <span class="hljs-number">14</span>  <span class="hljs-number">15</span>  <span class="hljs-number">160</span>  <span class="hljs-number">1</span>  <span class="hljs-number">1</span>  <span class="hljs-number">2</span>  <span class="hljs-number">1</span>  <span class="hljs-number">2</span>  <span class="hljs-number">2</span>  <span class="hljs-number">3</span>  <span class="hljs-number">1</span>  <span class="hljs-number">2</span>   <span class="hljs-number">2</span>   <span class="hljs-number">3</span>   <span class="hljs-number">2</span>   <span class="hljs-number">3</span>   <span class="hljs-number">3</span>   <span class="hljs-number">4</span>   <span class="hljs-number">1</span>
</code></pre><p>The pattern being formed above is the following:</p>
<blockquote>
<p>An even number, E, has the same number of bits as that of E / 2<br>An odd number, O, has one more bit than that of O / 2</p>
</blockquote>
<p>That’s all there is to see in the results above. This is the algorithm in its entirety. All we have to do is to iterate on numbers from <code>0..n</code> and use the two rules above and we solved the problem like a boss ?.</p>
<p>If you paid attention to the core idea of dynamic programming discussed during the beginning of the article, you’d know that this here, in essence, is a dynamic programming problem.</p>
<p>We make use of the result for a previous subproblem (smaller number) to calculate the answer (number of set bits) for the current subproblem.</p>
<p>On the face of it, we don’t need any bit manipulation as such to solve this problem. It can be solved by simple <code>if-else</code> clauses and a <code>for</code> loop.</p>
<p>So, this is not <em>really</em> a bitmasking + dynamic programming kind of problem.</p>
<p>Let’s look at a simple solution based on the ideas above.</p>
<p>This is a perfectly good way to solve this problem. For every index, <code>i</code>, we check the number of bits in the number <code>i / 2</code> and also add <code>1</code> if the current number is odd.</p>
<p>We can, however, solve it in a geekier way, so to say using bit manipulation. The two operations being performed are:</p>
<ol>
<li>division by 2 and</li>
<li>checking if the number is even or not.</li>
</ol>
<p>We have already seen the use of the right shift operator, <code>&amp;g</code>t;&gt;, for division by 2.</p>
<p>As for the second operation, we can simply check if the least significant is set or not. If you notice, all the odd numbers have their least significant bit set. While the even numbers don’t.</p>
<p>We have already seen how to check if a particular bit is set or not using the <code>AND</code> operator. Let’s see a geekier ? version of the above code.</p>
<p>If you look at the runtimes for both the programs, they’re almost the same. A major chunk of the time is consumed by the construction of the output array.</p>
<p>Bitwise operations are always optimized and are faster than other higher level programming constructs.</p>
<h3 id="heading-maximum-product-of-word-lengths">⛩ Maximum Product of Word Lengths ⛩</h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*-mkPWdUBpw3hcwVtKS0o0A.png" alt="Image" width="800" height="503" loading="lazy">
_Source: [LeetCode](https://leetcode.com/problems/maximum-product-of-word-lengths/description/" rel="noopener" target="<em>blank" title=")</em></p>
<p>There’s good news and bad news. The good news is that a slightly optimized version of the brute force algorithm will get your code accepted on the platform.</p>
<p>The brute force way is to check all the pairs of words and for each pair, check if there are any common characters between them. For all such pairs that don’t have any common characters, record the maximum value of <code>len(word1) * len(word2)</code>.</p>
<p>The bad news is that this algorithm is extremely slow. Let’s look at the percentage of solutions on LeetCode which this brute force algorithm is able to beat.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Htoctoz6g0CFKJPVTxj0jQ.png" alt="Image" width="800" height="461" loading="lazy"></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*ifXouPVw0R1oz1gdJrF_Lg.gif" alt="Image" width="480" height="360" loading="lazy">
_Source: [giphy](http://giphy.com" rel="noopener" target="<em>blank" title=")</em></p>
<p>Shame on you, Sachin!</p>
<p>That’s not the kind of stats you want to see for your submission. If you’re someone who simply wants to <em>solve</em> a problem, then your job here is done. Nothing more to do. But, if you’re like me and if you want to make this dog stop ?, then read on!</p>
<p>Let’s look at the time complexity for this brute force algorithm before moving onto a much more optimized solution using bit manipulation.</p>
<p>We consider all possible pairs of words from the given array. Considering there are <code>N</code> words in the given array, we will get <code>O(N²)</code> complexity right off the bat.</p>
<p>Other than that, we have a dictionary containing sets of characters for each of the words in the dictionary. Considering the size of the alphabet to be 26 (lowercase alphabets only), each set can potentially be of size <code>26</code>.</p>
<p>For each pair of words, we perform a set intersection to check whether the two words have any common characters or not. Set intersection takes linear time and hence, the overall complexity for this algorithm would come out to be <code>O(26N²)</code> which is essentially <code>O(N²)</code>.</p>
<p>It turns out that we can’t get rid of the part where we have to consider each pair of words from the given array. So, we can’t get rid of the <code>O(N²)</code> part of the algorithm.</p>
<p>The portion that we can get rid of, however, is the part where we compare two words and see if they have any common characters. That constant <code>26</code> slows down the algorithm a lot.</p>
<p>An important thing to note here is that the question simply cares about common characters and <strong>not their frequency or their order.</strong></p>
<blockquote>
<p>What if we simply use a bitmask to represent the characters in a word?</p>
</blockquote>
<p>What we can do here is to have a bitmask consisting of 26 bits to represents the characters belonging to a particular word. Let’s look at such a representation for a few words to make things clearer.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*MpHyWl7f6Kgoi5EDKlMczA.png" alt="Image" width="800" height="550" loading="lazy">
<em>Bitmaps for the three words: hello, algorithm, and tweet.</em></p>
<p>Hope the above figure makes it clear what we mean by a bitmask representing a corresponding word. Once we have these bitmasks for all the words, all that remains now is to check if two words have any common characters or not.</p>
<p>If two words would have any common characters, then the corresponding bits for those characters would be set in the bitmasks for both the words.</p>
<p>Hence, all we have to do is to do a bitwise <code>AND</code> of the bitmasks representing two words and check if we get a 0 or not. If we do end up getting a 0, that would imply no intersection and that is precisely what we are looking for.</p>
<pre><code>For e.g. Let<span class="hljs-string">'s consider two words "hello" and "jack"</span>
</code></pre><pre><code>The bitmask corresponding to <span class="hljs-string">"hello"</span> will have the bits <span class="hljs-keyword">for</span> <span class="hljs-string">'h'</span>, <span class="hljs-string">'e'</span>, <span class="hljs-string">'l'</span>, and <span class="hljs-string">'o'</span> set.
</code></pre><pre><code>The bitmask corresponding to <span class="hljs-string">"jack"</span> will have the bits <span class="hljs-keyword">for</span> <span class="hljs-string">'j'</span>, <span class="hljs-string">'a'</span>, <span class="hljs-string">'c'</span>, and <span class="hljs-string">'k'</span> set.
</code></pre><pre><code>Since these words don<span class="hljs-string">'t have any character in common, the bitwise AND of their bitmasks will give a 0.</span>
</code></pre><pre><code>Had there been any common characters between them, then both their bitmasks would have set bits at the same indexes (corresponding to the common letters) and hence we would get a non-zero bitwise AND.
</code></pre><p>Let’s look at the code for this modification in the algorithm we just discussed.</p>
<p>Bitwise operations are super quick. Let’s look at the performance of this algorithm on the LeetCode platform to corroborate the quickness of bit manipulation.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*7vAqZlPpq8qo8u7NyuoV8g.png" alt="Image" width="800" height="331" loading="lazy"></p>
<p>Not bad, right? We improved the runtime for our program from <em>1820 ms earlier to 712 ms now</em>. That’s a huge improvement, isn’t it? It turns out, we can improve this algorithm even further.</p>
<blockquote>
<p>The improvement can be made because of the fact that two different words can have the same bitmask.</p>
</blockquote>
<p>For e.g. <code>hello</code> and <code>llohhel</code> both would have the same bitmask. We can store the <em>longest word for a given bitmask since all we care about is maximizing the product of word lengths.</em></p>
<p>Let’s look at the code after incorporating this improvement.</p>
<p>By doing this very optimization, the runtime comes down to <strong>208ms ???</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*RoD7oopyw_564B0OaaTtaA.gif" alt="Image" width="600" height="600" loading="lazy">
_Source: [giphy](https://giphy.com/gifs/3o6ZtiLpjhjv9HVUti" rel="noopener" target="<em>blank" title=")</em></p>
<h3 id="heading-set-representation-using-bitmasking"><strong>Set Representation using Bitmasking</strong></h3>
<p><strong>We introduced an idea in the previous problem which will be crucial in the next two problems that we will discuss. Essentially, we used the idea of bitmasking to represent elements belonging to a set.</strong></p>
<p><strong>In the previous article, we considered a set of 26 alphabets and we resented that by using a bitmask containing 26 bits. A 0 at a particular index in the mask would represent set exclusion whereas a 1 would represent set inclusion.</strong></p>
<p><strong>This idea is very crucial for dynamic programming problems that deal with subproblems involving a subset of numbers. We can’t really cache a subset of numbers. A set is not a hashable data structure.</strong></p>
<p><strong><code>For e.g. suppose we have an array of numbers [4, 3, 6]</code></strong><br><strong><code>Let's look at all possible subsets of this array.[]</code></strong><br><strong><code>[4]</code></strong><br><strong><code>[3]</code></strong><br><strong><code>[6]</code></strong><br><strong><code>[4, 3]</code></strong><br><strong><code>[4, 6]</code></strong><br><strong><code>[3, 6]</code></strong><br><strong><code>[4, 3, 6]For dynamic programming problems where intermediate states are defined by these subsets, we need a memory efficient way of performing caching.</code></strong></p>
<p><strong>What do we do in such a scenario?</strong></p>
<p><strong>This is where we have bitmasks come in. They are memory-efficient ways of representing subsets of elements. Let’s have a look at how we can represent the subsets above using bitmasks.</strong></p>
<p><strong><code>Since we have 3 elements in our given array, [4, 3, 6] we can make use a a 3-bit number for representing each of these elements. An empty subset would be represented by 000. Let's look at each of the subsets along with their bit representations.000 --&gt;&gt; []</code></strong><br><strong><code>001 --&gt;&gt; [6]</code></strong><br><strong><code>010 --&gt;&gt; [3]</code></strong><br><strong><code>011 --&gt;&gt; [3, 6]</code></strong><br><strong><code>100 --&gt;&gt; [4]</code></strong><br><strong><code>101 --&gt;&gt; [4, 6]</code></strong><br><strong><code>110 --&gt;&gt; [4, 3]</code></strong><br><strong><code>111 --&gt;&gt; [4, 3, 6]</code></strong></p>
<p><strong>Depending upon the problem’s constraints, we can make use of a bitmask. For e.g. in the previous problem, the alphabet set was limited to the size 26. A lot of programming problems that have small array sizes and involve dynamic programming that require you to hash subsets, usually are an indication of bitmasking-based approach.</strong></p>
<p><strong>A 26-bit mask, e.g. in the previous problem, is essentially an integer and we can simply cache that integer in a dictionary. This saves on the memory footprint of the algorithm and greatly cuts down on the time complexity for the algorithm since bit manipulation is very efficient. We can easily include and exclude elements from the subset by masking and unmasking corresponding bits from the mask.</strong></p>
<p><strong>Let’s look at another problem based on this idea before we finally discuss the star problem of this article.</strong></p>
<h3 id="heading-partition-array-to-k-equal-sum-subsets"><strong>??Partition Array to K Equal Sum Subsets ??</strong></h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*RHsAK8OQJ6nGGu7MqrQccw.png" alt="Image" width="800" height="390" loading="lazy">
_Source: [LeetCode](https://leetcode.com/problems/partition-to-k-equal-sum-subsets/description/" rel="noopener" target="<em>blank" title=")</em></p>
<p><strong>This is just one of those questions that begs you to use bitmasking. Notice the size of the array. It’s just 16 elements. If we consider a bitmask to represent the elements in an array, we’d have a 16-bit integer at our hands.</strong></p>
<p><strong>That means, to represent all the possible subsets of a given array, we’d have 2¹⁶ possible integers. We don’t really need <em>actual</em> subsets. All we need is a bitmask telling us the elements belonging to that subset. Based on this idea, let’s look at dynamic programming-based approach to solve the above problem.</strong></p>
<p><strong>The problem statement only asks us if a k-equal-sum partitioning is possible or not. It doesn’t ask us to return the <em>actual</em> partitioning. That makes the problem a whole lot simpler.</strong></p>
<p><strong>We don’t care which partition an element belongs to as long as the overall sum of a partition is what <code>total_sum / k</code>.</strong></p>
<p><strong>As we’ve mentioned in the above paragraphs, we will be using a bitmask to represent the elements of the array.</strong></p>
<p><strong>We will use the individual bit states of the mask to identify which numbers have already been assigned a partition and which ones still remain to be assigned one. We can only assign a number to a partition if after adding it to that partition, the total sum remains <code>&lt;= total_sum</code> / k .</strong></p>
<p><strong>If the sum, <code>S</code>, of all the elements of the array is divisible by <code>k</code>, we have to complete <code>k — 1</code> partitions since the last partition will automatically fall into place. In case the total sum is not divisible by <code>k</code> , then such an equal sum partitioning is not possible.</strong></p>
<h4 id="heading-why-dynamic-programming"><strong>Why dynamic programming?</strong></h4>
<p><strong>Before looking at the code for this problem based on the ideas we’ve discussed above, it’s important to understand how dynamic programming fits into the picture. We’ve already seen why bitmasking would come in handy. But where exactly does dynamic programming fit in?</strong></p>
<p><strong>Recursion is a natural fit for the problem since we have got a set of <code>N</code> elements and we need to partition them into <code>k</code> different subsets all of which have an equal sum.</strong></p>
<p><strong>Since we don’t really know what partition a number should belong to, we have to try out all the options. That means, for a given partition, we try adding all available numbers recursively (within the constraints of the partition sum) and see which choice leads us to an answer.</strong></p>
<p><strong>The recursion would be based on the following three variables:</strong></p>
<ol>
<li><strong>the <code>number of partitions</code> remaining.</strong></li>
<li><strong>the <code>mask</code> representing what elements in the original array are <em>unassigned.</em></strong></li>
<li><strong>and the current <code>partition sum</code>.</strong></li>
</ol>
<p><strong>As we all know, for any problem to be classified as a dynamic programming problem, it should have the following two properties:</strong></p>
<ol>
<li><strong><em>Optimal sub-structure</em> ~ which simply means that the original problem must be breakable into subproblems and optimal solutions to the subproblems should be usable in a way to find the optimal solution to the main problem.</strong></li>
<li><strong><em>Overlapping subproblems</em> ~ which mean there are multiple recursive calls to the same subproblems and to avoid repeated computations, we can </strong><em>cache</em><strong> the results for our subproblems.</strong></li>
</ol>
<p><strong>Let’s look at the recursion tree for this problem to understand if we have any overlapping subproblems. We already have the first property satisfied.</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*uc66c1lYHTXfbnMLca2bXA.png" alt="Image" width="800" height="529" loading="lazy">
<em>The tuple <strong>(K, 12, 3)</strong> is the recursion state that gets repeated. K is the number of remaining partitions which in our example is 2. 12 is the current partition’s sum. 3 is the bitmask. If you consider the bitwise representation of 3, you will get 0011. That implies the two elements 5 and 7 from the set [8, 16, 5, 7] and hence the sum 12.</em></p>
<p><strong>In the above recursion tree, we consider K = 2. That means we need 2 partitions each of sum </strong>18<strong>. Since we never reach </strong>18<strong> in the tree above, the </strong>K<strong> never gets reduced. This is just a part of the recursion tree and the complete version.</strong></p>
<p><strong>We can clearly see two recursion states getting repeated. We get the same mask <code>0011</code> twice. We can simply store the result once and then re-use it later on.</strong></p>
<p><strong>Now let’s look at the code for based on bitmasking + dynamic programming.</strong></p>
<p><strong>Now we are finally ready to look at the main problem of this article. The problem that is not as straightforward in its bitmasking application as the current one and the previous one.</strong></p>
<h3 id="heading-find-the-shortest-superstring"><strong>? Find the Shortest Superstring ?</strong></h3>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*y3YKYQucMnTApO-_p8er2g.png" alt="Image" width="800" height="496" loading="lazy">
_Source: [LeetCode](https://leetcode.com/problems/find-the-shortest-superstring/description/" rel="noopener" target="<em>blank" title=")</em></p>
<p><strong>What do you think the simplest way of forming a <em>superstring</em> is?</strong></p>
<p><strong>You simply take any permutation of the given words and all of these permutations will be valid superstrings.</strong></p>
<p><strong>However, the question doesn’t ask us to form <em>any</em> superstring. It asks us to form the </strong>shortest superstring covering all the words.<em>**</em></p>
<p><strong>For this problem, we will explore the idea of </strong><em>chaining</em><strong> words together. Intuitively, you can consider the idea of chaining as set union.</strong></p>
<p><strong>Let’s consider two different set of elements and then look at the combined set containing all their elements together i.e. the union set.</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*X_PLM3rVNzJ6Oph9AFdJYQ.png" alt="Image" width="800" height="601" loading="lazy">
<em>The repeated elements are only considered once in the union.</em></p>
<p><strong>As we can see above, whenever we do a union over two sets, the common elements only appear once. We will adopt a similar idea with chaining two words together.</strong></p>
<p><strong>Essentially, when chaining words <code>A</code> and <code>B</code> together, we will only consider the common portion between the </strong><em>suffix of A and prefix of B exactly once.</em><em>**</em> Let’s look at the diagrammatic representation for chaining of two words.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*hCEiJ1aKvFBBmNkKbPi9jQ.png" alt="Image" width="800" height="570" loading="lazy"></p>
<p><strong>This is an important concept that will come in handy for solving this problem. So as to avoid repeated computations of finding out the </strong><em>common portion between two words which are being chained together,</em><strong> we will do some preprocessing.</strong></p>
<p><strong>We will find out the length of the suffix of <code>A</code> that overlaps with the prefix of <code>B</code> where <code>A and B</code> are being chained together. We will do this for all the pairs of words in our given list. In Python, given a string <code>S</code>, we can make use of <code>S[i:]</code> to obtain all the suffixes and <code>S[:i]</code> to obtain all the prefixes. We make use of this for our preprocessing below.</strong></p>
<p><strong>Now that the idea of chaining is clear, we can move onto the next part of the problem where we explain why this problem can be solved recursively.</strong></p>
<h4 id="heading-why-recursion"><strong>Why Recursion?</strong></h4>
<p><strong>Now that we are familiar with the concept of chaining, we know that whenever we chain two words together, the new word formed can be shorter than the combined lengths of the two original words.</strong></p>
<p><strong>Extending this idea to all the words in the given list, we have to form a superstring that will be formed by chaining one word after the other until we are done with all the words.</strong></p>
<p><strong>The important question here is, in what order should the words be chained together?</strong></p>
<p><strong>For the three words <code>aabc</code> , <code>hjaa</code>, and <code>chuj</code> the chaining order <code>hjaa → aabc → chuj = hjaabchuj</code> is better than <code>aabc → hjaa → chuj = aabchjaachuj</code> since the former gives a superstring of length 9 as opposed to 12 in the latter order.</strong></p>
<p><strong>So, the chaining order determines the overall length of the formed superstring.</strong></p>
<blockquote>
<p><strong>We will be <em>trying out all possible arrangements</em> for the superstrings using the given list of words and choosing the shortest one.</strong></p>
</blockquote>
<h4 id="heading-that-seems-legit-but-why-dynamic-programming"><strong>That seems legit, but why dynamic programming? ?</strong></h4>
<p><strong>Instead of relying on a recursion tree for explaining the need for dynamic programming, we will look at an example that will explain the same idea.</strong></p>
<p><strong>Suppose we are given a set of 5 words <code>[A, B, C, D, E]</code> and we are to form the shortest superstring that contains all the words.</strong></p>
<p><strong>We already know that we are solving this problem recursively. Suppose in the middle of our recursion, we are already done deciding the chaining order of the first 3 words. Let’s say this ordering was <code>B → A → C</code> . Now, we need to find out the best way to chain </strong>D and E after C so that the overall superstring length is minimized.<em>**</em></p>
<p><strong>Let’s say that in our recursion we found that <code>C → E → D</code> was the best chaining order. We don’t know yet if the superstring formed via <code>B → A → C → E → D</code> is the shortest one. However, we know that <code>C → E → D</code> is the best chaining order for the three words <code>C, D, and E</code> .</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*Job9SHPwsLUh3QBmMA-GRQ.gif" alt="Image" width="500" height="281" loading="lazy">
<em>I know it’s gotten tiring, but keep reading ?</em></p>
<p><strong>Suppose now we arranged the first three words a little differently in our recursion (a separate recursion path) and now we have <code>A → B → C</code> and we have to recurse </strong>again<strong> to find out the best possible arrangement for <code>E and D</code> . However, we already know from above the best possible arrangement is <code>C → E → D</code> . Why calculate this again? This is where dynamic programming comes into the picture.</strong></p>
<p><strong>That’s it? Go on. Explain some more.</strong></p>
<p><strong>Nah, let’s now look at the the Python code bringing all these ideas together.</strong></p>
<p><strong>Uh oh! Where the heck is bitmasking in all this?</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*YwOzvCoyJTdC59nj_vWmzA.gif" alt="Image" width="800" height="437" loading="lazy"></p>
<h4 id="heading-ok-ok-lets-get-to-bitmasking"><strong>Ok ok, let’s get to bitmasking ?</strong></h4>
<p><strong>Let’s rephrase the problem in a slightly different manner that will make the requirement for bitmasking very clear.</strong></p>
<p><strong>Given a set of <code>N</code> elements, we need to find a suitable arrangement for them that will minimize a certain metric. Since we are relying on dynamic programming, we will be <em>caching</em> results for subproblems<em>.</em></strong></p>
<p><strong>Our subproblems will be represented by the subset of these N items. As we’ve seen in this article and especially in the previous two problems, it’s difficult to cache subsets as it is.</strong></p>
<p><strong>In case the problem constraints are small, we can represent the elements of the list using a bitmask and use that for caching purposes.</strong></p>
<blockquote>
<p><strong>After all, a bitmask is just a number.</strong></p>
</blockquote>
<p><strong>Let’s finally get to the code for finding the shortest superstring given a set of N words.</strong></p>
<ul>
<li><strong>Line 3 ~</strong> The initial mask is composed of all 1s. That implies all the words are available for chaining. If the mask becomes 0, that means no word is left for chaining. So, the length of the superstring would be 0. This is the base case.</li>
<li><strong>Line 7 ~</strong> If you’ve paid attention to the example involving 5 words <code>[A, B, C, D, E]</code> from before, you know that the opportunity of caching arises when we have the two words <code>D and E</code> to be chained together <strong><em>following C.</em></strong><br><strong>_Thus, we need to know the previous word in the superstring so far so as to attach the rest of the words. Hence, <code>prev_i</code>, which represents the index in the original array of the previous word in the superstring is also used for caching purposes apart from the mask._</strong></li>
<li><strong>Line 12, 15 ~</strong> We always check all the given set of words and only consider those as <em>options for the current step in our recursion</em> which have not been previously used. We make use of bitmasking for this. To see if a word has been used or not, we simply check if the bit at the corresponding index in the mask is <em>unset</em> or not.</li>
<li><strong>Line 18 ~</strong> Makes use of the preprocessing we did earlier. For the word to be chained / attached to the word at index <code>prev_i</code> , we know the amount of overlap between the two. Thus, if we decide on considering the word at index <code>i</code> as the next word in our recursion, the amount of length it will add to our superstring would be <code>len(A[i]) — overlap between the words A[prev_i] and A[i]</code></li>
</ul>
<p><strong>All this is fine and dandy, but wasn’t the original question asking for the superstring itself and not just the length of the shortest superstring?</strong></p>
<p><strong>Am I shying away from solving the entire problem? Of course not!</strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*R45bEuJSmmUTZ10jOM4gdQ.gif" alt="Image" width="500" height="375" loading="lazy">
_Source: [giphy](https://giphy.com/gifs/no-smh-scooby-doo-EriPNV1whwKac" rel="noopener" target="<em>blank" title=")</em></p>
<p><strong>The function <code>recurse</code> simply returns the <em>length</em> of the shortest superstring and not the superstring itself. The problem statement, however, asks us to find out the shortest superstring.</strong></p>
<p><strong>If you look at the code carefully, you’ll notice a <code>parent</code> dictionary. At every step in our recursion, we have multiple options of words which can be chained to the current superstring (thus extending it). We use the parent dictionary to store the word at each step that gave the </strong><em>best</em><strong> answer (shortest length).</strong></p>
<p><strong>For a given mask — which tells us which words have already been chained together — and a given previous word (<code>prev_i</code>), the <code>parent</code> dictionary stores the next word that in the superstring that gives the optimal answer.</strong></p>
<p><strong>We will use this dictionary to backtrack and form the <em>shortest superstring.</em></strong></p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*IJ2Sm-YM_0ReJAhi907r5w.png" alt="Image" width="800" height="178" loading="lazy"></p>
<p><strong>In the end, that’s one of the best sights for a competitive programmer, especially if it’s for a hard problem in a timed competition.</strong></p>
<h3 id="heading-conclusion"><strong>Conclusion ??</strong></h3>
<ul>
<li><strong>Operations on bits are highly efficient and they are generally performed in parallel via optimized system level instructions.</strong></li>
<li><strong>It’s difficult, but not impossible, to write clean, understandable code involving bit manipulations.</strong></li>
<li><strong><code>AND</code> , <code>OR</code> , and <code>NOT</code> are the three fundamental bitwise operators.</strong></li>
<li><strong>The <code>left-shift &amp;l</code>t;&lt; an<code>d the right-sh</code>ift &gt;&gt; operators are used for multiplication or division by 2.</strong></li>
<li><strong>The <code>XOR</code> operator is a versatile operator that can be used in many different programming problems. It returns <code>True</code> only when both the bits are opposites and <code>False</code> otherwise.</strong></li>
<li><strong>Dynamic Programming-based solutions involve some sort of caching for the results of subproblems. The subproblems are represented by a set of variables. These variables are not necessarily primitive data types.</strong></li>
<li><strong>Bitmasking comes in very handy in dynamic programming problems when we have to deal with subsets and the list/array size is small. A mask (having all 0s or all 1s) can represent the elements of the set and setting or unsetting a bit can mean inclusion and exclusion from the set.</strong></li>
<li><strong>If the array/list/set size is, say, around 20, then you’d have 2²⁰ </strong><em>possible</em><strong> bitmasks which comes out to be almost a million of them. It’s not always the case you will encounter <em>all</em> of these bitmasks in a test case. However, that’s the maximum possible number.</strong></li>
<li><strong>We have to be careful about when to use bitmasking. We can’t have a 100-bit mask as that would be computationally intractable.</strong></li>
<li><strong>For a solution to be eligible for dynamic programming, it should satisfy the optimal substructure and the overlapping subproblems properties. Usually, through some practice, you can start to identify if the problem at hand will have a DP based solution or not.</strong></li>
</ul>
<h3 id="heading-references"><strong>References ?</strong></h3>
<ul>
<li><strong><a target="_blank" href="https://www.hackerearth.com/practice/notes/bit-manipulation/">https://www.hackerearth.com/practice/notes/bit-manipulation/</a></strong></li>
<li><strong><a target="_blank" href="https://blog.bitsrc.io/bitmask-there-is-space-at-the-bottom-5a741d18c4e3">https://blog.bitsrc.io/bitmask-there-is-space-at-the-bottom-5a741d18c4e3</a></strong></li>
<li><strong><a target="_blank" href="https://bit.ly/2QRTIpj">https://bit.ly/2QRTIpj</a></strong></li>
<li><strong><a target="_blank" href="https://bit.ly/2CCUCxn">https://bit.ly/2CCUCxn</a></strong></li>
<li><strong><a target="_blank" href="https://www.geeksforgeeks.org/bitmasking-and-dynamic-programming-set-1-count-ways-to-assign-unique-cap-to-every-person/">https://www.geeksforgeeks.org/bitmasking-and-dynamic-programming-set-1-count-ways-to-assign-unique-cap-to-every-person/</a></strong></li>
<li><strong><a target="_blank" href="https://www.geeksforgeeks.org/bitmasking-dynamic-programming-set-2-tsp/">https://www.geeksforgeeks.org/bitmasking-dynamic-programming-set-2-tsp/</a></strong></li>
<li><strong><a target="_blank" href="https://codeforces.com/blog/entry/17973">https://codeforces.com/blog/entry/17973</a></strong></li>
</ul>
<p><strong>It’s been a long article and one that I’ve absolutely loved writing. If you’ve read this far, then you’ve probably found this article really helpful. Do spread some love by sharing it as much as possible and destroy that clap button! ?</strong></p>
<p><strong>Oh, if you’d like to read more such awesome articles all lit up with animations and beautiful, explanatory images, do checkout our newly opened [</strong>kitchen<strong>](https://github.com/DivyaGodayal/CoderChef-Kitchen/).</strong></p>
<p><strong>Believe me, we’ve got some lip smacking recipes for you and with the holiday season upon us, I’m sure you’ll love them.</strong></p>
<p><strong>Wishing you all a Merry Christmas and a Happy New Year!</strong></p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
