<?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" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Faangshui - Algorithms, Data Structures & Coding Interviews]]></title><description><![CDATA[Demystifying Algorithms, Data Structures and Coding Interviews]]></description><link>https://blog.faangshui.com</link><image><url>https://substackcdn.com/image/fetch/$s_!uLrN!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F895e7a9e-879c-4fcf-a598-b65ecf31a271_1280x1280.png</url><title>Faangshui - Algorithms, Data Structures &amp; Coding Interviews</title><link>https://blog.faangshui.com</link></image><generator>Substack</generator><lastBuildDate>Tue, 21 Apr 2026 09:33:13 GMT</lastBuildDate><atom:link href="https://blog.faangshui.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Nurbo Kusmagul]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[faangshui@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[faangshui@substack.com]]></itunes:email><itunes:name><![CDATA[Nurbo Kusmagul]]></itunes:name></itunes:owner><itunes:author><![CDATA[Nurbo Kusmagul]]></itunes:author><googleplay:owner><![CDATA[faangshui@substack.com]]></googleplay:owner><googleplay:email><![CDATA[faangshui@substack.com]]></googleplay:email><googleplay:author><![CDATA[Nurbo Kusmagul]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Can You Find and Fix This Bug?]]></title><description><![CDATA[5-minute practice to sharpen your skills]]></description><link>https://blog.faangshui.com/p/can-you-find-and-fix-this-bug</link><guid isPermaLink="false">https://blog.faangshui.com/p/can-you-find-and-fix-this-bug</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Mon, 17 Feb 2025 13:57:55 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/73f5d81e-8622-457f-b7e5-326a0d970447_3605x2403.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Issue #2</strong> of the <strong>Bugbash</strong> challenge is out! This time, there are <strong>6 bugs</strong> to fix, available in <strong>12 languages</strong>. Below is the Python version of the qualification challenge. Can you spot the mistake and patch it up?</p><pre><code>def balanced_parentheses(self, str):
    count = 0
    for ch in str:
        if ch == '(':
            count += 1
        elif ch == ')':
            count -= 1
    return count == 0</code></pre><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/bugbash/chapters/january-collection/lessons/issue-2&quot;,&quot;text&quot;:&quot;Fix the bug&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://faangshui.com/books/bugbash/chapters/january-collection/lessons/issue-2"><span>Fix the bug</span></a></p><p>Put your debugging hat on and test your fix&#8212;along with <strong>5 other bugs</strong>&#8212;right here:<br><strong><a href="https://faangshui.com/books/bugbash/chapters/january-collection/lessons/issue-2">Bugbash Issue #2</a></strong></p><h2>Faangshui Lifetime Access with 30% Off</h2><p>The <strong>Lifetime Access</strong> to all Faangshui books and guides is on sale at a <strong>30% discount</strong>. If you want unlimited access to the Foundations course, interactive lessons, AI feedback, and more for just $69.30, you can grab it <strong><a href="https://faangshui.com/books/foundations/buy">here</a></strong>&#8212;offer ends soon!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/foundations/buy&quot;,&quot;text&quot;:&quot;Get Lifetime Premium for $69.30&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://faangshui.com/books/foundations/buy"><span>Get Lifetime Premium for $69.30</span></a></p><p></p><p><strong>Happy Bug Fixing!</strong><br><strong>Nurbo</strong></p>]]></content:encoded></item><item><title><![CDATA[Sliding Windows Explained]]></title><description><![CDATA[Why &#8220;windows&#8221; and why do they slide? Let&#8217;s find out!]]></description><link>https://blog.faangshui.com/p/sliding-windows-explained</link><guid isPermaLink="false">https://blog.faangshui.com/p/sliding-windows-explained</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Wed, 05 Feb 2025 14:57:18 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/7beed1ec-3a0d-43e6-a553-2633c965b7fe_5813x3707.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Have you ever heard the term &#8220;Sliding Windows&#8221;? Wondering why it&#8217;s called windows and why they slide? Let&#8217;s find out!</p><p>If you want to follow along with the built-in tasks and see the full guide, please read this guide on the <a href="https://faangshui.com/books/guides/chapters/core-concepts/lessons/sliding-windows">Faangshui platform</a>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/guides/chapters/core-concepts/lessons/sliding-windows&quot;,&quot;text&quot;:&quot;Read on Faangshui&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://faangshui.com/books/guides/chapters/core-concepts/lessons/sliding-windows"><span>Read on Faangshui</span></a></p><h3>A Simple Example</h3><p>Suppose we have a large array nums and want to find the sum of the first 10 elements &#8212; indices <code>0</code> to <code>9</code>. Think of this subarray as <code>window 1</code>. A window is just a subarray we&#8217;re interested in:</p><pre><code>sum_of_window1 = 0
for i in range(0, 10):
    sum_of_window1 += nums[i]
print("Sum of window 1:", sum_of_window1)
</code></pre><p>Now we&#8217;re curious about the next window, the subarray from indices <code>1</code> to <code>10</code> (2nd to 11th elements). We&#8217;re moving &#8212; or sliding &#8212; the window by one element to the right. We could recalculate its sum:</p><pre><code>sum_of_window2 = 0
for i in range(1, 11):
    sum_of_window2 += nums[i]
print("Sum of window 2:", sum_of_window2)</code></pre><p>But this repeats a lot of work. Notice that <code>window 2</code> differs from <code>window 1</code> by just two elements:</p><ul><li><p><code>nums[0]</code> is no longer included,</p></li><li><p><code>nums[10]</code> is newly included.</p></li></ul><p>Instead of looping again, we can update in constant time by subtracting the old element and adding the new one:</p><pre><code>sum_of_window2 = sum_of_window1 - nums[0] + nums[10]
print("Sum of window 2:", sum_of_window2)</code></pre><p>With just one subtraction and one addition, we reuse the previous window&#8217;s sum rather than recomputing from scratch. That&#8217;s the core of the sliding window approach &#8212; taking advantage of what we already know to avoid extra work.</p><p><strong>Why Does This Matter?</strong></p><p>If we need the sums of the first 100 windows (each of size 10), we can do:</p><pre><code># Calculate the sum of the first window
sum_of_window = 0
for i in range(0, 10):
    sum_of_window += nums[i]
print("Sum of window 1:", sum_of_window)

# Calculate sums of subsequent windows
for window_index in range(1, 100):
    sum_of_window = sum_of_window - nums[window_index - 1] + nums[window_index + 9]
    print("Sum of window", window_index + 1, ":", sum_of_window)</code></pre><p>Compare this to recalculating each window from scratch:</p><pre><code>for window_index in range(1, 100):
    sum_of_window = 0
    for i in range(window_index, window_index + 10):
        sum_of_window += nums[i]
    print("Sum of window", window_index + 1, ":", sum_of_window)</code></pre><p>You save a lot of time by avoiding an extra loop that runs k times (k = window size) for every shift of the window. Instead, you do just two operations per shift.</p><p><strong>The essence of the Sliding Windows technique:</strong></p><ol><li><p>Find and maintain a subarray (window) of a specific size or condition.</p></li><li><p>Slide the window to the next position by removing the old element(s) and adding the new element(s). Recompute in <code>O(1)</code> or <code>O(log(k))</code> time rather than <code>O(k)</code> each time.</p></li></ol><p>Use this approach wherever a rolling or continuous data segment is involved&#8212;sums, averages, min/max values, counts of distinct elements, and more.</p><p>Practice using sliding windows with the task below.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/guides/chapters/core-concepts/lessons/sliding-windows#the-flow-of-qi&quot;,&quot;text&quot;:&quot;See practice problem&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://faangshui.com/books/guides/chapters/core-concepts/lessons/sliding-windows#the-flow-of-qi"><span>See practice problem</span></a></p><div><hr></div><h2><strong>Fixed-Size vs Dynamic Sliding Windows</strong></h2><p>The fixed-size sliding window is a straightforward application, but often we encounter problems where the window size isn&#8217;t fixed but is determined by problem constraints. A classic example is finding the smallest subarray with a sum greater than or equal to a given target.</p><pre><code>nums = [2, 1, 5, 2, 3, 2]
target = 7</code></pre><p>Multiple subarrays of different sizes meet the condition (e.g., <code>[5, 2]</code>, <code>[2, 3, 2]</code>), but we seek the smallest one. A brute-force approach checks all subarrays, taking <code>O(n^2)</code> time&#8212;impractical for large arrays.</p><p><strong>Dynamic Sliding Window Approach</strong><br>Instead, let's use a dynamic sliding window in <code>O(n)</code> time. We will use two pointers, <code>left</code> and <code>right</code>, to manage the window&#8217;s boundaries, and move through subarrays akin to caterpillars crawling forward.</p><p><strong>Expand &amp; Shrink Strategy</strong></p><ul><li><p>Expand by moving <code>right</code> to the right until <code>current_sum</code> meets or exceeds <code>target</code>.</p></li><li><p>Shrink from the left by incrementing <code>left</code> while maintaining the sum condition, tracking the smallest subarray length found.</p></li><li><p>Once <code>current_sum</code> is less than <code>target</code>, we can expand again to the right.</p></li></ul><pre><code>left = 0
current_sum = 0
min_length = float('inf')

for right in range(len(nums)):
    current_sum += nums[right]

    # Shrink the window while current_sum &gt;= target
    while current_sum &gt;= target:
        min_length = min(min_length, right - left + 1)
        current_sum -= nums[left]
        left += 1

if min_length == float('inf'):
    print("No subarray found.")
else:
    print("Smallest subarray length:", min_length)</code></pre><p>Even though there are nested loops, the time complexity of this approach is <code>O(n)</code>, because <code>left</code> and <code>right</code> pointers move through the array only once. The space complexity is <code>O(1)</code>, because we are only using a few variables to track the state of the window.</p><p>We can summarize the dynamic sliding window approach as follows:</p><ol><li><p>Two Pointers (Left &amp; Right):</p><ul><li><p>Right pointer extends the window.</p></li><li><p>Left pointer shrinks the window when a condition is exceeded or met.</p></li></ul></li><li><p>Condition Checks:</p><ul><li><p>Could be a sum threshold, a character frequency limit, etc.</p></li><li><p>Move the left pointer whenever the condition is violated or satisfied (depending on problem needs).</p></li></ul></li><li><p>Track Answer:</p><ul><li><p>Continuously update the result (e.g., the shortest window that meets a sum, or the longest window of unique chars).</p></li></ul></li></ol><p>Sliding windows are a subset of Two Pointers, crucial for problems with variable-size windows. For a deeper dive into Two Pointers, explore the <strong><a href="http://127.0.0.1:3000/books/guides/chapters/core-concepts/lessons/index-pointers-aka-two-pointers">guide on Two Pointers / Index Pointers technique here</a></strong>.</p><p>Practice using dynamic sliding windows with the task below to master this powerful technique.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/guides/chapters/core-concepts/lessons/sliding-windows#the-candlelight-vigil&quot;,&quot;text&quot;:&quot;See practice problem&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://faangshui.com/books/guides/chapters/core-concepts/lessons/sliding-windows#the-candlelight-vigil"><span>See practice problem</span></a></p><div><hr></div><h2><strong>Frequency-Based Sliding Windows</strong></h2><p>So far, we&#8217;ve looked at summation-based sliding windows, where the state of the window is tracked by a single variable (the sum). Another common pattern is frequency-based sliding windows, where we track how many times each element (or character) appears in the window. Some examples include:</p><ul><li><p>Finding the longest substring with unique characters.</p></li><li><p>Locating subarrays that have at most k distinct elements.</p></li><li><p>Solving anagrams or frequency-based search problems.</p></li></ul><p>Let's start with a classic example of finding the longest substring with unique characters.</p><p>Task: given a string, find the length of the longest substring in which all characters are unique.</p><p>For example, given the string <code>"faangfaang"</code>, the longest substring with unique characters is <code>"angf"</code>, which has a length of 4.</p><p>We can solve this with a dynamic sliding window and a set to keep track of the characters in the window. Often you would use a hash map to keep track of the frequency of each character in the window, but in this problem, we only need to know if a character is in the window or not. The general approach is:</p><ol><li><p>"Expand" - move the right pointer and add the character to the set.</p></li><li><p>"Shrink" - if the character is already in the set, move the left pointer to the right until the character is no longer in the set.</p></li><li><p>At any moment, after the "Shrink" step, the set will contain only unique characters.</p></li><li><p>When expanding, update the maximum length of the substring with unique characters.</p></li></ol><pre><code>def longest_unique_substring(s):
    char_set = set()
    left = 0
    max_len = 0

    for right in range(len(s)):
        # If the character at 'right' is already in our set,
        # remove chars from the left until it's safe to add the new one
        while s[right] in char_set:
            char_set.remove(s[left])
            left += 1

        # Add the new character and update max_len
        char_set.add(s[right])
        max_len = max(max_len, right - left + 1)

    return max_len

# Example usage
s = "abcabcbb"
print(longest_unique_substring(s))  # Output: 3 (e.g., "abc")</code></pre><p>Frequency-based sliding windows let you handle frequency constraints within a subarray or substring. Notice that similar to summation-based sliding windows, frequency-based sliding windows performs the updates of the state of the window in <code>O(1)</code> time.</p><p>Practice using frequency-based sliding windows with the task below.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/guides/chapters/core-concepts/lessons/sliding-windows#the-calligraphy-contest&quot;,&quot;text&quot;:&quot;See frequency-based sliding window task&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://faangshui.com/books/guides/chapters/core-concepts/lessons/sliding-windows#the-calligraphy-contest"><span>See frequency-based sliding window task</span></a></p><div><hr></div><p>As always, you can access the full guide with built-in exercises on <a href="https://faangshui.com/books/guides/chapters/core-concepts/lessons/sliding-windows">the Faangshui platform</a>.</p><p>Happy Coding!</p><p>Nurbo</p>]]></content:encoded></item><item><title><![CDATA[Five-Minute Algorithm Practice]]></title><description><![CDATA[Squash Bugs and Sharpen Your Skills on Faangshui]]></description><link>https://blog.faangshui.com/p/five-minute-algorithm-practice</link><guid isPermaLink="false">https://blog.faangshui.com/p/five-minute-algorithm-practice</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Wed, 29 Jan 2025 14:24:50 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/e3e2c6e9-a200-4e9b-9661-d516862ac3e1_1200x900.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I&#8217;ve been cooking up something new on the Faangshui platform, and I&#8217;m excited to share it with you today: <strong>Bugbash</strong>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/bugbash/chapters/january-collection/lessons/issue-1&quot;,&quot;text&quot;:&quot;Try Bugbash Here&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://faangshui.com/books/bugbash/chapters/january-collection/lessons/issue-1"><span>Try Bugbash Here</span></a></p><h2>What&#8217;s Bugbash?</h2><p>It&#8217;s a short coding challenge where you&#8217;ll fix bugs in an algorithmic function. Instead of solving big problems from scratch, you&#8217;ll spend just a few minutes <strong>actively reading</strong> and <strong>debugging</strong>. Why? Because reading code is one of the best ways to sharpen your algorithmic skills&#8212;but it can get dull if it&#8217;s too passive. Finding bugs keeps it <strong>engaging</strong>, <strong>memorable</strong>, and, dare I say, <strong>fun</strong>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/bugbash/chapters/january-collection/lessons/issue-1&quot;,&quot;text&quot;:&quot;Try Bugbash Here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://faangshui.com/books/bugbash/chapters/january-collection/lessons/issue-1"><span>Try Bugbash Here</span></a></p><h2>How It Works</h2><ul><li><p><strong>Six Bug-Fixing Tasks</strong></p><ul><li><p><strong>One Qualifier</strong>: This task lets you dip your toes in without pressure.</p></li><li><p><strong>Five Main Tasks</strong>: These are the timed challenges that count toward your final score.</p></li></ul></li><li><p><strong>Scoring</strong></p><ul><li><p>Your score depends on <strong>how fast</strong> you squash the bugs and <strong>how many</strong> failed attempts you make.</p></li><li><p>There&#8217;s also a <strong>leaderboard</strong> so you can see how you stack up against others.</p></li></ul></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/bugbash/chapters/january-collection/lessons/issue-1&quot;,&quot;text&quot;:&quot;Try Bugbash Here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://faangshui.com/books/bugbash/chapters/january-collection/lessons/issue-1"><span>Try Bugbash Here</span></a></p><h2>Why It&#8217;s Worth a Try</h2><ol><li><p><strong>Minimal Time Required</strong><br>Each Bugbash challenge should take you only a few minutes&#8212;perfect if you&#8217;re busy but want a quick mental exercise.</p></li><li><p><strong>Active Code Reading</strong><br>You&#8217;ll get better at understanding and parsing code by spotting and fixing errors instead of passively reading.</p></li><li><p><strong>Explore Faangshui</strong><br>If you haven&#8217;t visited the Faangshui platform yet, Bugbash is a fun way to dip your toes in. It&#8217;s quick, interactive, and you&#8217;ll see what the platform is all about.</p></li></ol><div><hr></div><h2>Give Bugbash a Go!</h2><p>Head over to <strong>faangshui.com/bugbash</strong> to try the first challenge. It&#8217;s a small time commitment, but it could make a big difference in your problem-solving skills. Plus, I&#8217;d love to hear your thoughts on this new feature&#8212;your feedback helps me make the platform better for everyone.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/bugbash/chapters/january-collection/lessons/issue-1&quot;,&quot;text&quot;:&quot;Try Bugbash Here&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://faangshui.com/books/bugbash/chapters/january-collection/lessons/issue-1"><span>Try Bugbash Here</span></a></p><p>Take care, and happy bug-hunting!</p><p><strong>Nurbo</strong></p>]]></content:encoded></item><item><title><![CDATA[Beyond Two Pointers]]></title><description><![CDATA[A Complete Guide to Index-Based Problem Solving]]></description><link>https://blog.faangshui.com/p/beyond-two-pointers</link><guid isPermaLink="false">https://blog.faangshui.com/p/beyond-two-pointers</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Tue, 21 Jan 2025 16:13:11 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/98d0776c-49af-46dd-9f7a-de917079d347_626x479.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2><strong>Beyond Two Pointers</strong></h2><p>The term &#8220;two pointers&#8221; gets mentioned often, but it&#8217;s really not a single, one-size-fits-all method. Think of it as a flexible strategy &#8212; sometimes you only need one pointer, other times three or more. In this guide, we&#8217;ll explore how pointers of all kinds can tackle different challenges, showing that &#8220;two pointers&#8221; is just the beginning.</p><p>I recommend you to follow this guide with embedded practice problems on the new <a href="https://link.faangshui.com/pointers">Faangshui platform here</a>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button&quot;,&quot;text&quot;:&quot;See the interactive guide on Faangshui&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button"><span>See the interactive guide on Faangshui</span></a></p><div><hr></div><p><strong>What is a Pointer?</strong></p><p>In C, a pointer is a variable that holds the memory address of another variable. For example:</p><pre><code>int array[3] = {1, 2, 3};
int *pointer = &amp;array[0];
printf("First element is %d\n", *pointer); // prints 1

*pointer = 10;  // change the first element
printf("Now first element is %d\n", array[0]); // prints 10

pointer++; // move pointer to the next element
printf("Second element is %d\n", *pointer); // prints 2
</code></pre><p>Because we have the address of an element in an array, we can directly access or modify its value, or shift the pointer itself (pointer arithmetic). This flexibility is what makes pointers powerful.</p><p><strong>Index Pointers in High-Level Languages</strong></p><p>In higher-level languages like Python or JavaScript, we don&#8217;t typically manipulate raw memory addresses. Instead, we store an index that effectively points to an element in an array. Think of RAM as an array of bytes &#8212; tracking an index is like using a &#8220;pointer&#8221; into that array. You can read, modify, or move to other elements by changing the index.</p><p>To distinguish from low-level memory address pointers, we&#8217;ll call these index pointers. Although pointers can apply to linked lists as well, this guide focuses on index pointers in arrays.</p><div><hr></div><p><strong>Single Pointer</strong></p><p>You&#8217;ve likely already used a single pointer without realizing it. A basic example is finding the index of the maximum value in an array:</p><pre><code>max_pointer = 0
for i in range(len(nums)):
    if nums[i] &gt; nums[max_pointer]:
        max_pointer = i
print(f"The index of the maximum value is {max_pointer}")
</code></pre><p>Here, max_pointer stores the index of the currently most interesting element&#8212;in this case, the largest value so far. As the loop progresses, this pointer updates whenever a new maximum is found.</p><p><strong>Practice Task</strong><br>Practice using <a href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#index-of-the-minimum">single pointers here</a>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#index-of-the-minimum&quot;,&quot;text&quot;:&quot;Practice Single Pointers&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#index-of-the-minimum"><span>Practice Single Pointers</span></a></p><div><hr></div><h2><strong>Pointers Over Multiple Arrays</strong></h2><p>Sometimes you&#8217;ll need to work with multiple arrays where standard linear traversal isn&#8217;t possible because you can&#8217;t simply iterate from the beginning to the end of one array. In these cases, you can use multiple single pointers &#8212; one for each array.</p><p><strong>Example: Merging Two Sorted Arrays</strong><br>Task: given two sorted arrays, merge them into a single sorted array.</p><pre><code>nums1 = [1, 2, 3]
nums2 = [2, 5, 6]
merged_array = [1, 2, 2, 3, 5, 6]
</code></pre><p>Since you can&#8217;t just iterate linearly from start to finish in either array (you don&#8217;t know which element is next in sorted order), index pointers are ideal.</p><p><strong>Defining the Pointers</strong></p><ul><li><p><code>pointer1</code>: Tracks the current position in <code>nums1</code> &#8212; the next element not yet added to <code>merged_array</code>.</p></li><li><p><code>pointer2</code>: Tracks the current position in <code>nums2</code> &#8212; the next element not yet added to <code>merged_array</code>. Initially, both pointers start at index 0 of their respective arrays.</p></li></ul><p><strong>Merging Process</strong></p><ul><li><p>Compare <code>nums1[pointer1]</code> and <code>nums2[pointer2]</code>.</p></li><li><p>Whichever element is smaller goes into <code>merged_array</code>, and the corresponding pointer is incremented.</p></li><li><p>Repeat until one pointer reaches the end of its array.</p></li><li><p>Append any remaining elements from the other array.</p></li></ul><pre><code>pointer1 = 0
pointer2 = 0
merged_array = []

while pointer1 &lt; len(nums1) and pointer2 &lt; len(nums2):
    if nums1[pointer1] &lt; nums2[pointer2]:
        merged_array.append(nums1[pointer1])
        pointer1 += 1
    else:
        merged_array.append(nums2[pointer2])
        pointer2 += 1

# Append remaining elements from nums1 or nums2.
while pointer1 &lt; len(nums1):
    merged_array.append(nums1[pointer1])
    pointer1 += 1

while pointer2 &lt; len(nums2):
    merged_array.append(nums2[pointer2])
    pointer2 += 1
</code></pre><p>Notice that <code>pointer1</code> and <code>pointer2</code> move independently. Each pointer is responsible for tracking progress in its own array.</p><p><strong>Practice Task</strong><br>Practice using pointers over multiple arrays in the task <a href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#the-triple-scroll-merge">linked here</a>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#the-triple-scroll-merge&quot;,&quot;text&quot;:&quot;Practice Multiple Pointers&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#the-triple-scroll-merge"><span>Practice Multiple Pointers</span></a></p><div><hr></div><h2><strong>Fast and Slow Pointers</strong></h2><p>Fast and slow pointers are a clever technique for working with arrays or linked structures. They move at different speeds to tackle a range of problems&#8212;everything from detecting cycles to in-place array modifications.</p><p><strong>Example: Removing Duplicates in a Sorted Array</strong><br>Task: remove duplicates while keeping all unique elements at the beginning.</p><pre><code>slow = 0
for fast in range(1, len(nums)):
    if nums[fast] != nums[slow]:
        slow += 1
        nums[slow] = nums[fast]
</code></pre><p><strong>How It Works</strong></p><ul><li><p>Fast pointer: Scans through every element in the array.</p></li><li><p>Slow pointer: Keeps track of where the next unique element should be placed.</p></li><li><p>Writing unique values: Each time <code>nums[fast]</code> is different from <code>nums[slow]</code>, move <code>slow</code> forward and store <code>nums[fast]</code> there.</p></li></ul><p>By the time you finish iterating:</p><ul><li><p>All unique elements are compacted at the front of the array.</p></li><li><p><code>slow</code> indicates the index of the last unique element.</p></li></ul><p>This approach processes the array in a single pass (O(n) time), making it highly efficient for sorting and deduplication tasks.</p><p><strong>Practice Task</strong><br>Practice using fast and slow pointers in the task <a href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#the-flowing-stream">linked here</a>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#the-flowing-stream&quot;,&quot;text&quot;:&quot;Practice Fast and Slow Pointers&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#the-flowing-stream"><span>Practice Fast and Slow Pointers</span></a></p><div><hr></div><h2><strong>Converging Pointers</strong></h2><p>The converging pointers technique places two pointers at opposite ends of an array and moves them toward each other based on specific conditions. It&#8217;s commonly used for problems involving comparisons, finding pairs, or narrowing search spaces in a sorted array.</p><p><strong>Example: Two-Sum in a Sorted Array</strong><br>Task: given a sorted array and a target sum, find two numbers that add up to the target.</p><pre><code>left = 0
right = len(nums) - 1

while left &lt; right:
    sum = nums[left] + nums[right]
    if sum == target
        return [left, right]
    elif sum &lt; target
        left += 1
    else
        right -= 1
</code></pre><p><strong>How it works:</strong></p><ol><li><p>Initialize pointers: set <code>left</code> at the start and <code>right</code> at the end of the array.</p></li><li><p>Evaluate and adjust:</p><ul><li><p>If <code>nums[left] + nums[right]</code> equals the target, the solution is found.</p></li><li><p>If the sum is too small, move <code>left</code> rightward to increase it.</p></li><li><p>If the sum is too large, move <code>right</code> leftward to decrease it.</p></li></ul></li><li><p>Stop condition: continue until the pointers meet or you&#8217;ve found a valid pair.</p></li></ol><p>Because the array is sorted, every pointer adjustment precisely eliminates a chunk of the search space. Each element is examined at most once, resulting in an efficient O(n) solution.</p><p><strong>Practice Task</strong><br>Practice using converging pointers in the task <a href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#the-mirror-of-words">linked here</a>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#the-mirror-of-words&quot;,&quot;text&quot;:&quot;Practice Converging Pointers&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#the-mirror-of-words"><span>Practice Converging Pointers</span></a></p><div><hr></div><h2><strong>Role-Based Pointers</strong></h2><p>Role-Based Pointers is a technique where each pointer has a specific task or role, allowing you to address different parts of a problem at the same time. Unlike other pointer techniques where pointers often depend on one another, in this approach each pointer operates independently based on its assigned role.</p><p><strong>Example: Rearranging Even/Odd Elements by Index</strong><br>Task: rearrange an array so that even indices hold even numbers and odd indices hold odd numbers. Assume the array has an equal number of even and odd elements.</p><pre><code>nums = [3, 1, 2, 4]
result = [2, 3, 4, 1]</code></pre><p><strong>Solution Using Role-Based Pointers</strong><br>Let's define two pointers:</p><ul><li><p><code>even_idx</code>: Tracks the next even index where an even number should go.</p></li><li><p><code>odd_idx</code>: Tracks the next odd index where an odd number should go.</p></li></ul><p>Here is how the code looks:</p><pre><code>even_idx = 0
odd_idx = 1

while even_idx &lt; len(nums) and odd_idx &lt; len(nums):
    if nums[even_idx] % 2 == 0:
        even_idx += 2  # Even number is in the correct position
    elif nums[odd_idx] % 2 == 1:
        odd_idx += 2  # Odd number is in the correct position
    else:
        swap(nums[even_idx], nums[odd_idx])
</code></pre><p>Each pointer has a specific role:</p><ul><li><p><code>even_idx</code>: Ensures even numbers are at even indices, moving forward only when the condition is met.</p></li><li><p><code>odd_idx</code>: Ensures odd numbers are at odd indices, moving forward only when the condition is met. If each pointer finds a number at the wrong index, a swap corrects both simultaneously.</p></li></ul><p>By assigning each pointer its own job, this problem becomes a series of straightforward checks and swaps rather than a single pointer juggling multiple conditions.</p><p><strong>Practice Task</strong><br>Practice using role-based pointers in the task <a href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#sorting-the-three-realms">linked here</a>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#sorting-the-three-realms&quot;,&quot;text&quot;:&quot;Practice Role-Based Pointers&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#sorting-the-three-realms"><span>Practice Role-Based Pointers</span></a></p><div><hr></div><h2><strong>Binary Search</strong></h2><p>Yes, you read that right &#8212; binary search can be seen as an index pointers problem. It&#8217;s an algorithm that uses pointers (indexes) to locate a target value in a sorted array efficiently. These pointers mark the boundaries of the search space, and at each step, you check the midpoint to decide which half of the array to explore next.</p><p><strong>Intuition behind binary search</strong><br>Imagine searching for a specific page in a book:</p><ul><li><p>Open roughly in the middle.</p></li><li><p>Check if the target page is earlier or later than where you opened.</p></li><li><p>Move left or right, halving the search area until you find the page. Binary search applies this same strategy to an array, repeatedly dividing the problem space in half.</p></li></ul><p><strong>Example: Finding an Element in a Sorted Array</strong><br>Task: find the index of <code>7</code> in the sorted array <code>nums = [2, 4, 7, 10, 14, 15, 17, 29, 45]</code>.</p><ol><li><p>Start with two pointers:</p><ul><li><p><code>low = 0</code> (the first index).</p></li><li><p><code>high = len(nums) - 1 = 8</code> (the last index).</p></li></ul></li><li><p>Calculate the midpoint:</p><ul><li><p><code>mid = (low + high) // 2 = (0 + 8) // 2 = 4</code>.</p></li></ul></li><li><p>Check if <code>nums[mid]</code> is the target:</p><ul><li><p><code>nums[4] = 14</code>, which is not the target.</p></li></ul></li><li><p>Narrow down the search space:</p><ul><li><p>Since 7 is less than 14, we know it must be in the left half.</p></li><li><p>Update <code>high = mid - 1 = 4 - 1 = 3</code>.</p></li></ul></li><li><p>Calculate the new midpoint:</p><ul><li><p><code>mid = (low + high) // 2 = (0 + 3) // 2 = 1</code>.</p></li></ul></li><li><p>Check if <code>nums[mid]</code> is the target:</p><ul><li><p><code>nums[1] = 4</code>, which is not the target.</p></li></ul></li><li><p>Narrow down the search space:</p><ul><li><p>Since 7 is greater than 4, we know it must be in the right half.</p></li><li><p>Update <code>low = mid + 1 = 1 + 1 = 2</code>.</p></li></ul></li><li><p>Calculate the new midpoint:</p><ul><li><p><code>mid = (low + high) // 2 = (2 + 3) // 2 = 2</code>.</p></li></ul></li><li><p>Check if <code>nums[mid]</code> is the target:</p><ul><li><p><code>nums[2] = 7</code>, which is the target.</p></li></ul></li><li><p>Return the index of the target:</p><ul><li><p>The index of 7 is 2.</p></li></ul></li></ol><p>This is a simple example, but binary search can handle much larger arrays and more complex search conditions. Putting it into code, you get:</p><pre><code>low = 0
high = len(nums) - 1

while low &lt;= high:
    mid = (low + high) // 2
    if nums[mid] == target:
        return mid
    elif nums[mid] &lt; target:
        low = mid + 1
    else:
        high = mid - 1

return -1  # Target not found
</code></pre><p><strong>Variations of Binary Search</strong><br>Many versions of binary search exist, such as:</p><ul><li><p>Lower bound / upper bound: find the first or last position of a value.</p></li><li><p>Search insert position: identify where a target should be inserted if not present.</p></li><li><p>Rotated array search: adaptations for arrays rotated around a pivot.</p></li></ul><p>Binary search&#8217;s power lies in its logarithmic time complexity, making it efficient for large datasets. Give it a try in the practice task <a href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#the-scroll-of-greater-wisdom">linked here</a> to sharpen your skills.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#the-scroll-of-greater-wisdom&quot;,&quot;text&quot;:&quot;Practice Pointers in Binary Search&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button#the-scroll-of-greater-wisdom"><span>Practice Pointers in Binary Search</span></a></p><div><hr></div><h2><strong>Two Pointers Summary</strong></h2><p>Throughout this guide, we explored how index pointers can efficiently solve an array of problems by focusing on specific positions, traversing arrays in custom orders, or using multiple pointers to handle different tasks. Here are the key takeaways:</p><p><strong>1. Indices Are Just Numbers</strong><br>Think of indices as ordinary integers stored in variables. You can add, subtract, or otherwise manipulate them. When you use these index variables to navigate an array, they effectively act as pointers.</p><p><strong>2. Track Important Positions</strong><br>In many problems, certain positions in an array matter more than others. By assigning pointers to track these positions, you can isolate, modify, or compare them as needed, all within a single pass or minimal passes over the data.</p><p><strong>3. Custom Traversals</strong><br>You&#8217;re not restricted to a simple for-loop from start to finish. Index pointers let you move through the array in any order, skipping or revisiting elements based on problem-specific logic.</p><p><strong>4. Beyond Arrays</strong><br>While we focused on arrays, the same pointer logic can apply to linked lists, strings, or even trees. Anywhere you deal with references or indices, pointer-based approaches can shine.</p><p><strong>5. Sorted Order is a Hint</strong><br>Though not mandatory, a sorted array often suggests that pointers can solve the problem. Even if an array isn&#8217;t sorted initially, you can sort it first and then apply two-pointer methods for more efficient solutions.</p><div><hr></div><p>By keeping these principles in mind, you&#8217;ll be able to recognize where pointers can simplify your solutions and optimize your algorithms, whether you&#8217;re dealing with arrays, lists, or other data structures.</p><p>Check out the practice tasks on index pointers to sharpen your skills: <strong><a href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-two-pointers-practice-problems?utm_source=newsletter&amp;utm_medium=button">Index Pointers / Two Pointers Practice Problems</a></strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button&quot;,&quot;text&quot;:&quot;See the interactive guide on Faangshui&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://faangshui.com/books/bootcamp/chapters/core-concepts/lessons/index-pointers-aka-two-pointers?utm_source=newsletter&amp;utm_medium=button"><span>See the interactive guide on Faangshui</span></a></p><p>Happy coding,</p><p>Nurbo</p>]]></content:encoded></item><item><title><![CDATA[My Coding Interview Prep Book Is Live!]]></title><description><![CDATA[Faangshui.com]]></description><link>https://blog.faangshui.com/p/my-coding-interview-prep-book-is</link><guid isPermaLink="false">https://blog.faangshui.com/p/my-coding-interview-prep-book-is</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Tue, 14 Jan 2025 12:50:24 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/1214863f-2642-4b22-8dab-895d56b40860_1410x2250.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi friend!</p><p>It's been a while since my last update. <strong>Tomorrow</strong>, I'll send you an article on the Two Pointers (or <em>dynamic pointers</em>) technique. But today, I wanted to share what I&#8217;ve been working on: <strong>The <a href="https://link.faangshui.com/newsletter">Faangshui platform</a></strong> at <a href="https://link.faangshui.com/newsletter">faangshui.com</a> and the first interactive book on the platform, called <strong>Foundations</strong>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://link.faangshui.com/newsletter&quot;,&quot;text&quot;:&quot;Check out Faangshui&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://link.faangshui.com/newsletter"><span>Check out Faangshui</span></a></p><div><hr></div><h2>Why I Created the Platform</h2><p>The idea behind <strong>Faangshui</strong> is simple: make coding interview prep <strong>accessible</strong> and <strong>fun</strong>. I like Leetcode, and I enjoy books like <em>CLRS</em>, but I believe there's a way to make learning algorithmic problem-solving even more engaging.</p><div><hr></div><h2>What Makes It Fun?</h2><h3><strong>Quest-Like Structure</strong></h3><p>The course is designed as a journey, complete with interactive story elements to keep you motivated.</p><p><strong>The Story</strong>: A digital plague has thrown your village into chaos. Desperate for a solution, the elders send you to the legendary Faangshui Temple. Can you master the algorithms and techniques needed to restore the systems and save your home?</p><p>Progressing through the book is like moving through chapters of an epic quest, with each solved problem bringing you closer to saving your village.</p><h3><strong>Inline Code Editor</strong></h3><p>Test your solutions <strong>immediately</strong> after reading the theory. Theory and practice in one place!</p><h3><strong>151+ Progressive Problems</strong></h3><p>Problems grow in difficulty at a manageable pace, helping you steadily build confidence and skills. I&#8217;m adding more problems every day.</p><h3><strong>Beginner-Friendly, Yet Engaging for Intermediates</strong></h3><p>Even if you have some Leetcode experience, you&#8217;ll find challenges that deepen your problem-solving capabilities.</p><h3><strong>AI Feedback from the Faangshui Spirit</strong></h3><p>Get automated, helpful commentary on your code as you go&#8212;making the learning process more interactive and insightful.</p><p>I&#8217;m not entirely sure if I achieved everything I set out to do&#8212;you tell me!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://link.faangshui.com/newsletter&quot;,&quot;text&quot;:&quot;Check out Faangshui&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://link.faangshui.com/newsletter"><span>Check out Faangshui</span></a></p><div><hr></div><h2>Who&#8217;s It For?</h2><p><strong>Foundations</strong> is the course you should take <em>before</em> diving into Leetcode, or if you&#8217;re currently struggling with the so-called &#8220;Easy&#8221; problems. The goal is to help you build your <strong>algorithmic problem-solving skills (APSS)</strong> so you can tackle any algorithm or data structure with confidence.</p><h3><strong>Topics Covered:</strong></h3><ul><li><p>Accumulators</p></li><li><p>Loops</p></li><li><p>Indexing</p></li><li><p>Dynamic Pointers (Two Pointers)</p></li><li><p>Sliding Windows</p></li><li><p>Counters</p></li><li><p>Hash Tables</p></li></ul><p><strong>More advanced topics</strong> are on the way, and I plan to publish new lessons every week!</p><div><hr></div><h2>Check It Out!</h2><p>I&#8217;d love your feedback on both the <strong>Faangshui</strong> platform and the <strong>Foundations</strong> book. Your insights help me improve the learning experience for everyone.</p><p>Stay tuned for <strong>tomorrow&#8217;s</strong> article on the Two Pointers technique (a.k.a. <em>dynamic pointers</em>). In the meantime, feel free to explore <a href="https://faangshui.com/">faangshui.com</a> and let me know what you think!</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://link.faangshui.com/newsletter&quot;,&quot;text&quot;:&quot;Check out Faangshui&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="https://link.faangshui.com/newsletter"><span>Check out Faangshui</span></a></p><p><strong>Happy Coding,</strong></p><p>Nurbo</p>]]></content:encoded></item><item><title><![CDATA[How to Talk to the Interviewer]]></title><description><![CDATA[Interview Communication 101]]></description><link>https://blog.faangshui.com/p/how-to-talk-to-the-interviewer</link><guid isPermaLink="false">https://blog.faangshui.com/p/how-to-talk-to-the-interviewer</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Wed, 06 Nov 2024 16:15:53 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/23c2c50a-1d29-4f87-963d-b0deb6481d3e_1920x1280.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The most important soft skill for a coding interview is <strong>communication</strong>. Effective communication is essential not just to impress the interviewer&#8212;which is still important&#8212;but also to eliminate confusion and ensure the interview progresses smoothly.</p><p>To excel in communication during your interview, you don't have to be an extrovert or pretend to be overly friendly. There are two key components to effective communication during interviews:</p><ol><li><p><strong>Keep the interviewer informed.</strong></p></li><li><p><strong>Listen to and acknowledge interviewer feedback.</strong></p></li></ol><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.faangshui.com/subscribe?"><span>Subscribe now</span></a></p><h2>Keep the Interviewer Informed</h2><p>At any moment, the interviewer should know what you're doing. You don't have to talk constantly unless you want to. What's important is to tell the interviewer what you plan to do next, especially during transitions&#8212;moments when you start doing something new.</p><p>Here is a list of common transitions with example phrases you could use:</p><h4><strong>1. After the Interviewer Presents You the Problem</strong></h4><p><em>"Alright, let me reread the problem description to see if I have any questions."</em></p><h4><strong>2. After You Fully Understand the Problem and Need Time to Think</strong></h4><p><em>"I think I understand the problem now. Let me think about possible approaches."</em></p><h4><strong>3. After You Have Explained Your Approach</strong></h4><p><em>"Does this sound reasonable to you?"</em></p><h4><strong>4. Before Starting Implementation</strong></h4><p><em>"I'd like to start implementing this unless you'd like me to explore further optimizations."</em></p><h4><strong>5. During Major Sections of Coding</strong></h4><p>For every significant section of code, briefly explain what you're doing. There's no need to comment on every line&#8212;you can keep quiet while you're coding.</p><ul><li><p><em>"First, I'll count the occurrences of these words in the text."</em></p></li><li><p><em>"Here, I'm going to implement a helper function to check if the state is valid."</em></p></li></ul><h4><strong>6. If You Get Stuck at Any Point</strong></h4><p>If you're unsure about something, express your thoughts aloud.</p><ul><li><p><em>"I'm thinking about whether there's a better way to implement this function."</em></p></li><li><p><em>"Perhaps it would be easier to use a hash set here instead of a hash table."</em></p></li></ul><h4><strong>7. After Finishing Coding&#8212;Don't Just Say "I'm Done"</strong></h4><p>Testing is crucial. Begin with a quick code review.</p><p><em>"Alright, let me quickly walk through the code to make sure I haven't missed anything."</em></p><h4><strong>8. Testing the Code with a Real Example</strong></h4><p>After the quick check and fixing any obvious bugs, test your code with an actual input.</p><p><em>"Now, let me test the code with this input to make sure it works as intended."</em></p><h4><strong>9. While Running the Input</strong></h4><p>Narrate the key steps your code is performing. Focus on important variables and state changes, not every single line. Don&#8217;t forget &#8212; you are testing this for yourself, not for the interviewer.</p><ul><li><p><em>"Here, the array is initialized with zeroes."</em></p></li><li><p><em>"Because the condition is satisfied, we'll exit the loop and return the result."</em></p></li></ul><h4><strong>10. After Thoroughly Checking Your Code</strong></h4><p><em>"I think this code should work."</em></p><div><hr></div><p>If you keep quiet, the interviewer might feel that you're struggling. If they do, they may provide unnecessary help, which could negatively affect your interview assessment. To avoid confusion, communicate with the interviewer when it's important to do so.</p><div><hr></div><h2>Listen for Feedback</h2><p>There may be moments when the interviewer notices you're heading down the wrong path. They might tell you directly or indirectly, while you're explaining your approach or implementing your solution. In these moments, don't dismiss the interviewer's feedback. Take the time to understand their concern and then either:</p><h4><strong>1. Politely Acknowledge if You Already Had a Plan to Address It</strong></h4><p><em>"Ah, I see your point. I'll address that separately."</em></p><h4><strong>2. Admit and Fix the Issue</strong></h4><p><em>"Thanks for the pointer! Let me think about how I can fix this..."</em></p><p>Interviewers rarely interrupt unless there's a real issue in your approach or code. Show the interviewer that you can receive feedback and resolve potential issues sooner rather than later.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Faangshui! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>Final Thoughts</h2><p>Effective communication during a coding interview doesn't mean you have to be overly talkative or extroverted. By keeping the interviewer informed and actively listening to their feedback, you demonstrate professionalism, confidence, and the ability to collaborate&#8212;qualities highly valued in a software engineer.</p><p>Remember, the goal is to make the interview a smooth experience for both you and the interviewer. Clear communication helps prevent misunderstandings and showcases your problem-solving process, increasing your chances of success.</p><div><hr></div><p><strong>Stay curious and happy coding!</strong></p><p><strong>Nurbo</strong></p><p></p><h2>I'm Accepting New Mentees!</h2><p>Are you looking for a mentor to guide you and keep you accountable on your tech interview preparation journey? I'm here to help.</p><p>I'm opening up a few spots for motivated individuals who would benefit from weekly one-on-one mentorship sessions. Together, we'll:</p><ul><li><p><strong>Develop a personalized study plan</strong></p></li><li><p><strong>Master problem-solving techniques</strong></p></li><li><p><strong>Build confidence for your interviews</strong></p></li></ul><p><strong>Ready to take your preparation to the next level?</strong> Book a <strong>free introductory session</strong> with me <a href="https://link.faangshui.com/book">here</a>.</p>]]></content:encoded></item><item><title><![CDATA[The Key to Effective Leetcoding is ChatGPT]]></title><description><![CDATA[Maximizing Your Coding Interview Preparation with Smart Strategies]]></description><link>https://blog.faangshui.com/p/the-key-to-effective-leetcoding-is</link><guid isPermaLink="false">https://blog.faangshui.com/p/the-key-to-effective-leetcoding-is</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Fri, 01 Nov 2024 14:56:09 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/258fe791-5436-42be-82c2-d3ffc2bfe850_500x260.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>With over <strong>3,340 problems</strong> on Leetcode as of today, attempting to solve them all is neither practical nor efficient. If you spent just 20 minutes per problem, dedicating 8 hours a day without breaks, it would take you approximately <strong>140 days</strong> to get through them all. Clearly, this isn't the best use of your time or resources when preparing for coding interviews.</p><p>There's a smarter way to leverage Leetcode in your preparation, and it involves combining foundational skills with the power of <strong>ChatGPT</strong>.</p><div><hr></div><h2>Before You Dive into Leetcode</h2><p>Before jumping into Leetcode problems, it's crucial to build your foundational <strong>Algorithmic Problem-Solving Skills (APSS)</strong>. This doesn't require deep knowledge of algorithms and data structures beyond basic constructs like loops, arrays, conditionals, and perhaps hash tables.</p><p>Focusing on strengthening your APSS ensures that you can approach problems logically and creatively, setting a solid foundation for learning more advanced topics later on. You can find a list of problems to build your foundational APSS in the article below.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;0db33f30-66d6-4316-b0f9-a79539e1ce19&quot;,&quot;caption&quot;:&quot;Many people feel discouraged when they struggle to solve even the \&quot;Easy\&quot; problems on Leetcode. But it's not their fault. There should be another level called \&quot;Pre-Easy\&quot; or \&quot;Foundational\&quot; that focuses on building the problem-solving muscle, guiding folks gradually into more advanced levels. In fact, I believe you can be 90% ready for your coding intervie&#8230;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Before Leetcode&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:15832389,&quot;name&quot;:&quot;Nurbo Kusmagul&quot;,&quot;bio&quot;:&quot;Mastering Algorithms &amp; Data Structures | Follow for Clear, Fun, and Practical Tech Knowledge&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ae212a87-4f50-4e9a-8570-9022fc4a1836_1740x1740.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-09-18T20:44:03.224Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8ee4cc0-f619-45b1-8add-3f56e6c5b49c_2000x1334.jpeg&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://blog.faangshui.com/p/before-leetcode&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:149072585,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:17,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Faangshui - Algorithms, Data Structures &amp; Coding Interviews&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F895e7a9e-879c-4fcf-a598-b65ecf31a271_1280x1280.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><h2>Leveraging ChatGPT + Leetcode</h2><p>Once you've established a strong foundation in APSS, it's time to dive into theory and practice. Here's how you can effectively use <strong>ChatGPT</strong> alongside Leetcode to optimize your preparation.</p><h3><strong>Step 1: Learn the Theory with ChatGPT</strong></h3><p>Use ChatGPT to learn and understand key concepts in algorithms and data structures.</p><p><strong>Example Prompt:</strong></p><p><em>"I'm preparing for my coding interviews and I want to learn the stack data structure. Explain this data structure to me as the best teacher in the world would and show me how to use it with a few basic problems."</em></p><p>ChatGPT can provide clear explanations, examples, and answer any follow-up questions you might have. This interactive learning helps solidify your understanding before you tackle actual problems.</p><h3><strong>Step 2: Get a Curated List of Problems</strong></h3><p>After grasping the theory, ask ChatGPT to provide a list of Leetcode problems related to the topic.</p><p><strong>Example Prompt:</strong></p><p><em>"Give me a list of 10 Leetcode problems of increasing difficulty that must be solved using stacks."</em></p><p>This approach ensures that you're practicing problems directly related to the concept you've just learned, reinforcing your understanding through application.</p><div><hr></div><h2>Solving Problems on Leetcode</h2><p>Now that you have a tailored list of problems, it's time to put your skills to the test.</p><h3><strong>Time Management</strong></h3><ul><li><p><strong>Set a Timer</strong>: Start the built-in timer on Leetcode.</p></li><li><p><strong>Allocate 20 Minutes</strong>: Spend up to 20 minutes devising an approach to the problem.</p></li></ul><h3><strong>Problem-Solving Approach</strong></h3><ul><li><p><strong>Doodle and Diagram</strong>: Sketch out examples and think through the problem visually.</p></li><li><p><strong>Relate to Examples</strong>: Consider how the problem relates to the examples provided by ChatGPT.</p></li><li><p><strong>Identify Patterns</strong>: Look for patterns or similarities with problems you've solved before.</p></li></ul><h3><strong>When You Get Stuck</strong></h3><p>If you can't find the right approach after 20 minutes, it's a sign that you may need more practice or that the problem is currently too challenging.</p><p><strong>Option 1: Seek Intuition</strong></p><p>Prompt ChatGPT for guidance without requesting the full solution.</p><p><strong>Example Prompt:</strong></p><p><em>"Explain the intuition for the Leetcode problem 'Evaluate Reverse Polish Notation' without providing any code or the solution."</em></p><p>This helps you gain insights into the problem while still allowing you to work through the solution independently.</p><p><strong>Option 2: Adjust the Difficulty</strong></p><p>If you've successfully solved a few problems but are struggling with the next one, the difficulty jump might be too steep.</p><p><strong>Example Prompt:</strong></p><p><em>"I was able to solve 'Valid Parentheses' and 'Min Stack,' but I'm struggling with 'Largest Rectangle in Histogram.' Can you suggest a couple of other Leetcode problems that are slightly easier but will help me prepare for this one?"</em></p><p>This way, you can progressively build up to more challenging problems.</p><h3><strong>Achieving Mastery</strong></h3><p>Continue this process until you can solve at least <strong>five consecutive medium-level problems</strong> on the topic on your own. This consistency indicates a strong grasp of the topic.</p><div><hr></div><h2>How to Save Time</h2><p>Once you're comfortable with a topic and have solved several problems independently, you can optimize your practice sessions.</p><h3><strong>Selective Implementation</strong></h3><ul><li><p><strong>Outline Solutions</strong>: For every other problem, read the problem statement and outline your approach without coding.</p></li><li><p><strong>Verify with Solutions</strong>: Compare your approach with the official solutions or discussions.</p></li><li><p><strong>Code When Necessary</strong>: If your approach differs or you feel uncertain, take the time to implement the solution.</p></li></ul><p><strong>Note:</strong> Only adopt this strategy if you're confident in your coding abilities. If you need to improve your coding skills, it's advisable to implement every solution.</p><div><hr></div><h2>Applying Binary Search to Identify Your Level</h2><p>After covering all the major topics, it's time to simulate the unpredictability of real interviews.</p><h3><strong>Step 1: Prepare the List</strong></h3><ul><li><p><strong>Filter Problems</strong>: On Leetcode, filter for unsolved medium-level problems.</p></li><li><p><strong>Sort by Acceptance Rate (High to Low)</strong>: This often correlates with difficulty.</p></li></ul><h3><strong>Step 2: Binary Search Your Skill Level</strong></h3><ul><li><p><strong>Start in the Middle</strong>: There are 1,800 medium problems, begin in the middle on page 9. Pick any problem on the page.</p></li><li><p><strong>Assess and Adjust</strong>:</p><ul><li><p><strong>If You Solve It Easily</strong>: Move forward by a few hundred problems (page 14).</p></li><li><p><strong>If You Struggle</strong>: Move backward to page 4.</p></li><li><p>Keep doing this until you find your approximate level.</p></li></ul></li></ul><p>This method helps you find the range of problems that match your current skill level.</p><h3><strong>Step 3: Focused Practice</strong></h3><p>Once you've identified your level:</p><ul><li><p><strong>Solve Problems Down The List</strong>: These problems will have slightly lower acceptance rate and are generally considered more difficult.</p></li><li><p><strong>Track Your Progress</strong>: Aim to solve several problems consecutively to build confidence.</p></li><li><p><strong>Skip Ahead If Needed</strong>: As you improve, probe ahead and challenge yourself with problems that have even lower acceptance rates.</p></li></ul><div><hr></div><h2>What About Blind-75 Or Neetcode-150?</h2><p>These lists are okay, but they are more useful to folks who have already built strong APSS. Mind you, they do not cover all problem types and they don&#8217;t necessarily represent the most frequently asked interview problems. They are there just to provide some structure.</p><p>I think you are better off just using ChatGPT to create your own custom problem lists.</p><div><hr></div><h2>How Many Problems Should You Solve?</h2><p>The number varies depending on individual factors like experience and proficiency.</p><ul><li><p><strong>Minimum Recommendation</strong>: Aim to solve at least <strong>10 problems per major topic</strong>.</p></li><li><p><strong>Quality Over Quantity</strong>: It's better to deeply understand and internalize solutions to 150 problems than to superficially attempt 500.</p></li><li><p><strong>Personalize Your Goal</strong>: Assess your confidence and readiness rather than fixating on a specific number.</p></li></ul><p><strong>Remember:</strong> Some may reach readiness after solving 30 problems, especially with prior experience. Others might need more practice, and that's perfectly okay.</p><div><hr></div><h2>Final Thoughts</h2><p>Preparing for coding interviews is not about the sheer volume of problems you solve but about <strong>effective learning and consistent practice</strong>. By leveraging tools like ChatGPT and employing strategic approaches to problem-solving, you can make your preparation more efficient and less overwhelming.</p><p><strong>Key Takeaways:</strong></p><ul><li><p><strong>Build a Strong Foundation</strong>: Strengthen your APSS before diving into complex problems.</p></li><li><p><strong>Use ChatGPT Wisely</strong>: It's a valuable resource for learning theory and getting tailored practice problems.</p></li><li><p><strong>Practice Efficiently</strong>: Focus on understanding rather than rote memorization.</p></li><li><p><strong>Assess Your Level</strong>: Use binary search on Leetcode to find problems that match your skill level.</p></li><li><p><strong>Quality Matters</strong>: Deep understanding of fewer problems is more beneficial than a superficial grasp of many.</p></li></ul><div><hr></div><h2>Request For Topics</h2><p>The topic of today&#8217;s issue was kindly suggested by Atman and the previous one was inspired by a question from Pavel. Kudos to you guys!</p><p>If there are questions or topics you want to read about in the next issue, comment below or email me.</p><p>As always, you can book a <strong>free introductory coaching session</strong> with me <a href="https://link.faangshui.com/book">here</a>.</p><p></p><p><strong>Stay curious and happy coding!</strong></p><p><strong>Nurbo</strong></p>]]></content:encoded></item><item><title><![CDATA[Why the Tortoise and the Hare Algorithm Works]]></title><description><![CDATA[Demystifying Floyd's Cycle Detection Algorithm]]></description><link>https://blog.faangshui.com/p/why-the-tortoise-and-the-hare-algorithm</link><guid isPermaLink="false">https://blog.faangshui.com/p/why-the-tortoise-and-the-hare-algorithm</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Tue, 29 Oct 2024 17:38:17 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/dc2d6070-7149-4ca9-b011-2d3b6d07d328_1024x1024.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I was recently asked by a mentee about the Tortoise and Hare algorithm, and I realized that many people find it confusing. I remember being puzzled by it myself when I first encountered it. In this article, I'll try to clarify how this algorithm works and why it's effective for cycle detection.</p><div><hr></div><h2>The Problem: Cycle Detection</h2><p>First, let's understand the problem the algorithm addresses. The <strong>cycle detection problem</strong> involves determining whether a linked structure (like a linked list) contains a cycle. In other words, we need to check if there's a way to start from a node and follow a sequence of links that eventually loops back to the same node.</p><p>A straightforward solution is to traverse the linked list while keeping track of the nodes we've visited using a hash table (or a set). If we reach a node we've seen before, we know there's a cycle. If we reach the end (a <code>null</code> pointer) without encountering a repeated node, there's no cycle.</p><p>This method works fine and has a time complexity of O(N), where N is the number of nodes, but it requires O(N) additional space to store the visited nodes.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.faangshui.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>Introducing the Tortoise and Hare Algorithm</h2><p>The <strong>Tortoise and Hare algorithm</strong>, also known as <strong>Floyd's Cycle Detection Algorithm</strong>, offers a way to detect cycles using only constant O(1) space, while maintaining O(N) time complexity.</p><h3>How It Works</h3><ul><li><p><strong>Two Pointers</strong>: We use two pointers to traverse the linked list:</p><ul><li><p><strong>Tortoise (Slow Pointer)</strong>: Moves one node at a time.</p></li><li><p><strong>Hare (Fast Pointer)</strong>: Moves two nodes at a time.</p></li></ul></li><li><p><strong>Cycle Detection</strong>:</p><ul><li><p><strong>If there's no cycle</strong>: The hare will reach the end of the list (a <code>null</code> pointer) before the tortoise.</p></li><li><p><strong>If there's a cycle</strong>: The hare will eventually lap the tortoise, and they will meet at some node within the cycle.</p></li></ul></li></ul><div><hr></div><h2>Understanding Why It Works</h2><h3>Intuitive Explanation</h3><p>Imagine you and a friend are running on a circular track:</p><ul><li><p><strong>You (Tortoise)</strong>: Run at a steady pace (one lap per hour).</p></li><li><p><strong>Your Friend (Hare)</strong>: Runs twice as fast (two laps per hour).</p></li></ul><p>If you both start at the same point, your friend will lap you after one hour because they're running twice as fast. Even if you start at different points, your friend will eventually catch up to you because they're moving faster on the same loop.</p><p>In the context of a linked list with a cycle, the hare moves through the nodes twice as fast as the tortoise. If there's a cycle, the hare will "lap" the tortoise and they will meet inside the cycle.</p><h3>Why the Hare Doesn't Overjump the Tortoise</h3><p>A common question is: <strong>Why doesn't the hare skip over the tortoise without meeting it?</strong></p><p>Since the hare moves two steps for every one step the tortoise takes, the distance between them decreases by one node on each move:</p><ul><li><p>If the hare is K nodes behind the tortoise, after each move, the gap reduces by one.</p></li><li><p>Eventually, the hare will catch up to the tortoise.</p></li></ul><p>In other words, the speed of the hare relative to the speed of the tortoise, is only one node per iteration. It is as if the tortoise is standing in its place while the hare is moving one node at a time. Because the hare gets closer (in a cycle) or further (without a cycle) only one node at a time, there is no way for the hare to skip over the tortoise.</p><h3>Where Do They Meet?</h3><p>If there is a cycle, the tortoise and hare will meet somewhere within the cycle. The exact node where they meet depends on the length of the non-cyclic part of the list and the length of the cycle.</p><div><hr></div><h2>Finding the Start of the Cycle</h2><p>Once we've detected a cycle (when the tortoise and hare meet), we might want to find the node where the cycle begins.</p><h3>The Algorithm</h3><ol><li><p><strong>Reset the Tortoise</strong>: Move the tortoise pointer back to the head of the list.</p></li><li><p><strong>Move Both Pointers at the Same Speed</strong>: Now, both the tortoise and hare move one step at a time.</p></li><li><p><strong>Point of Intersection</strong>: The node where they meet again is the start of the cycle.</p></li></ol><h3>Why Does This Work?</h3><p>Let's break it down mathematically:</p><ul><li><p>Let:</p><ul><li><p><strong>L</strong> be the length of the non-cyclic part (nodes before the cycle starts).</p></li><li><p><strong>C</strong> be the length of the cycle.</p></li><li><p><strong>M</strong> be the distance from the start of the cycle to the point where the tortoise and hare first meet within the cycle.</p></li></ul><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!n5PD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d6debc4-1a20-4b33-98fe-0554f1298744_1599x829.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!n5PD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d6debc4-1a20-4b33-98fe-0554f1298744_1599x829.png 424w, https://substackcdn.com/image/fetch/$s_!n5PD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d6debc4-1a20-4b33-98fe-0554f1298744_1599x829.png 848w, https://substackcdn.com/image/fetch/$s_!n5PD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d6debc4-1a20-4b33-98fe-0554f1298744_1599x829.png 1272w, https://substackcdn.com/image/fetch/$s_!n5PD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d6debc4-1a20-4b33-98fe-0554f1298744_1599x829.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!n5PD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d6debc4-1a20-4b33-98fe-0554f1298744_1599x829.png" width="1456" height="755" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3d6debc4-1a20-4b33-98fe-0554f1298744_1599x829.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:755,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:142010,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!n5PD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d6debc4-1a20-4b33-98fe-0554f1298744_1599x829.png 424w, https://substackcdn.com/image/fetch/$s_!n5PD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d6debc4-1a20-4b33-98fe-0554f1298744_1599x829.png 848w, https://substackcdn.com/image/fetch/$s_!n5PD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d6debc4-1a20-4b33-98fe-0554f1298744_1599x829.png 1272w, https://substackcdn.com/image/fetch/$s_!n5PD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3d6debc4-1a20-4b33-98fe-0554f1298744_1599x829.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg role="img" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><title></title><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li><li><p>At the first meeting point:</p><ul><li><p>The tortoise has traveled <strong>L + M</strong> steps.</p></li><li><p>The hare has traveled <strong>L + M + N * C</strong> steps, where <strong>N</strong> is the number of full cycles the hare has completed (N &#8805; 1).</p></li><li><p>Since the hare moves twice as fast, <strong>Hare's distance = 2 * (Tortoise's distance)</strong>:</p></li></ul></li></ul><pre><code>2(L + M) = L + M + N * C</code></pre><ul><li><p>Simplify the equation:</p></li></ul><pre><code>2L + 2M = L + M + N * C
=&gt; (2L - L) + (2M - M) = N * C
=&gt; L + M = N * C</code></pre><ul><li><p>This means <strong>L + M</strong> is a multiple of <strong>C</strong>.</p></li><li><p>When we reset the tortoise to the head and move both pointers one step at a time:</p><ul><li><p>The tortoise moves <strong>L</strong> steps to reach the start of the cycle.</p></li><li><p>The hare, starting from the meeting point, will also move <strong>L</strong> steps (since it's <strong>N * C - M</strong>, which simplifies to <strong>L</strong> due to the earlier equation), and they will meet at the cycle's starting node.</p></li></ul></li></ul><h3>Intuitive Explanation</h3><p>Let M be the distance from the start of the cycle to the point where the tortoise and hare first meet within the cycle. By moving tortoise back to the start, we are kind of resetting the race. But this time, we are giving the hare a head start of exactly M positions. What it means is that now tortoise and hare will meet M positions sooner, which is exactly where the start of the cycle is.</p><div><hr></div><h2>Applications Beyond Linked Lists</h2><p>The Tortoise and Hare algorithm isn't limited to linked lists. It can be applied to any scenario where we can model the problem as moving through states with possible cycles.</p><h3>Examples</h3><h4><strong>1. Find the Duplicate Number</strong></h4><p>Given an array of integers <code>nums</code> containing <code>n + 1</code> integers where each integer is in the range <code>[1, n]</code> inclusive. There is only one repeated number in <code>nums</code>, return this repeated number.</p><p><strong>Constraints:</strong></p><ul><li><p>You must solve the problem without modifying the array <code>nums</code> and use only constant extra space.</p></li></ul><p><strong>Solution:</strong></p><ul><li><p><strong>Modeling as a Linked List</strong>: Treat the array as a linked list where each index is a node, and the value at each index points to the next node.</p></li><li><p><strong>Applying Tortoise and Hare</strong>: Use the cycle detection algorithm to find the duplicate number, which corresponds to the start of the cycle.</p></li><li><p><strong>LeetCode Problem</strong>: Find the Duplicate Number</p></li></ul><h4><strong>2. Happy Number</strong></h4><p>A <strong>happy number</strong> is a number defined by the following process:</p><ul><li><p>Starting with any positive integer, replace the number by the sum of the squares of its digits.</p></li><li><p>Repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle that does not include 1.</p></li><li><p>Those numbers for which this process ends in 1 are happy.</p></li></ul><p>Return <code>true</code> if <code>n</code> is a happy number, and <code>false</code> if not.</p><p><strong>Solution:</strong></p><ul><li><p><strong>Modeling the Process</strong>: Each number generated is a state, and we can consider the process as moving from one state to another.</p></li><li><p><strong>Applying Tortoise and Hare</strong>: Use the algorithm to detect if there's a cycle (which would mean the number is not happy).</p></li><li><p><strong>LeetCode Problem</strong>: Happy Number</p></li></ul><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.faangshui.com/subscribe?"><span>Subscribe now</span></a></p><h2>Is This Algorithm Useful for Interviews?</h2><p><strong>Yes and No.</strong></p><h3><strong>Yes:</strong></h3><ul><li><p><strong>Demonstrates Deep Understanding</strong>: Knowing the Tortoise and Hare algorithm shows that you have a solid grasp of algorithmic techniques and can apply them to solve problems efficiently with optimal space complexity.</p></li><li><p><strong>Useful for Certain Problems</strong>: Some interview problems are best solved using this algorithm, especially when space constraints are tight.</p></li></ul><h3><strong>No:</strong></h3><ul><li><p><strong>Challenging to Derive on the Spot</strong>: Unless you're familiar with the algorithm beforehand, it's unlikely you'll come up with it during an interview under time pressure.</p></li><li><p><strong>Acceptable Alternatives</strong>: Interviewers generally accept solutions that use hash tables to detect cycles, even if they use O(N) space, as long as the time complexity is acceptable and the solution is correct.</p></li></ul><h3><strong>My Recommendation</strong></h3><ul><li><p><strong>Familiarize Yourself</strong>: Even if you don&#8217;t stumble upon a cycle detection problem or won&#8217;t use the algorithm in your solution, it's beneficial to understand this strategy.</p></li><li><p><strong>Communicate with the Interviewer</strong>: If space complexity is a concern, mention that you know an O(1) space solution using the Tortoise and Hare algorithm.</p></li><li><p><strong>Use the Best Approach You Know</strong>: If you're unsure about implementing the algorithm correctly, it's better to use a method you're confident with, like using a hash table to track visited nodes.</p></li></ul><div><hr></div><h2>Conclusion</h2><p>The Tortoise and Hare algorithm is a clever technique for detecting cycles with constant space complexity. Understanding why it works can deepen your grasp of algorithmic concepts and might give you an edge in interviews.</p><p>Remember:</p><ul><li><p><strong>Cycle Detection</strong>: Two pointers moving at different speeds can detect cycles when they meet.</p></li><li><p><strong>Finding Cycle Start</strong>: Resetting one pointer to the head and moving both at the same speed leads to the cycle's entry point.</p></li><li><p><strong>Applications</strong>: Beyond linked lists, the algorithm applies to any sequence of states with potential cycles.</p></li></ul><p>Stay curious and happy coding!</p><p>Nurbo</p><div><hr></div><h2>Batch Mentorship Session Bookings Available Now</h2><p>By popular request I just enabled batch-bookings for my mentorship sessions.</p><p>If you book 10 sessions at once, you will save $200. Just follow <a href="https://link.faangshui.com/batch-of-10">this link</a> to book all 10 sessions or just book the first of the 10 and you can book the rest later.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Faangshui! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Get Your APSS in Shape!]]></title><description><![CDATA[Strengthening Your Algorithmic Problem-Solving Skills]]></description><link>https://blog.faangshui.com/p/get-your-apss-in-shape</link><guid isPermaLink="false">https://blog.faangshui.com/p/get-your-apss-in-shape</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Fri, 25 Oct 2024 13:18:06 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/2be7b6eb-cf4d-4310-9c3a-9092ac85d4b6_600x400.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A lot of folks who want to prepare for their coding interviews and take a shot at FAANGs or other top tech companies make the same critical mistake. They start with a list like Blind-75 or Neetcode-150, hoping to memorize solutions and patterns. Unfortunately, 90% of people get frustrated while working on these lists and give up on their dreams. The remaining 10% may go through the list by checking every other solution, but still end up frustrated because they fail when they encounter a problem they haven&#8217;t seen before.</p><h2>Build Your APSS</h2><p>The first thing you need to do is build your <strong>Algorithmic Problem-Solving Skills (APSS)</strong>. This is a skill set that can be trained and doesn't require deep knowledge of algorithms and data structures beyond the basic constructs such as loops, arrays, conditionals, and perhaps hash tables. If your APSS are strong, it's easy to learn new algorithms or data structures as needed. In fact, learning a new algorithm will be similar to working on a new APSS-strengthening exercise. On the other hand, even if you've memorized all the algorithms and data structures, you may struggle to solve a random problem thrown at you during your interview if your APSS are weak.</p><p>If this all sounds too cryptic, here is an example of an APSS-strengthening problem that doesn&#8217;t require any advanced knowledge:</p><div><hr></div><h3><strong>Example: Print a Spiral Matrix</strong></h3><p>Write a function that takes an integer <strong>n</strong> and prints an <strong>n x n</strong> matrix in spiral order, starting with the number 1 in the top-left corner and ending with <strong>n&#178;</strong> in the center. The matrix should be filled in a clockwise spiral, incrementing each value by 1 as you go.</p><p><strong>For n = 5, the output would be:</strong></p><pre><code> 1  2  3  4  5
16 17 18 19  6
15 24 25 20  7
14 23 22 21  8
13 12 11 10  9</code></pre><p>As you can see in this problem, there is no advanced algorithm involved. All you need to solve this problem are loops and an array. If your APSS are in shape, you'll be able to devise a solution by carefully simulating the spiral traversal and filling in the numbers accordingly.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.faangshui.com/subscribe?"><span>Subscribe now</span></a></p><div><hr></div><h2>Why Focus on APSS?</h2><ul><li><p><strong>Foundation for Complex Problems and Algorithms</strong>: Strong problem-solving skills are the foundation upon which you can build knowledge of advanced algorithms and data structures.</p></li><li><p><strong>Adaptability</strong>: Interviews often present unique problems. Relying solely on memorized solutions won't help if you can't adapt your thinking to new scenarios.</p></li><li><p><strong>Confidence</strong>: Developing APSS boosts your confidence in tackling unfamiliar problems, reducing anxiety during interviews.</p></li></ul><div><hr></div><h2>How to Build Stronger APSS</h2><p>APSS exercises vary depending on your current level. In general, APSS problems don&#8217;t require any more knowledge than you already have. These are stretch exercises that make you more agile with your current knowledge.</p><p>For beginners, that usually means problems solvable with just arrays, loops and conditionals. You can later add hash tables and recursion to that list. I have shared a list of APSS-building problems for beginners here: </p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;c4020677-afbf-4b0b-aeb5-a10a7da1c31f&quot;,&quot;caption&quot;:&quot;Many people feel discouraged when they struggle to solve even the \&quot;Easy\&quot; problems on Leetcode. But it's not their fault. There should be another level called \&quot;Pre-Easy\&quot; or \&quot;Foundational\&quot; that focuses on building the problem-solving muscle, guiding folks gradually into more advanced levels. In fact, I believe you can be 90% ready for your coding intervie&#8230;&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Before Leetcode&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:15832389,&quot;name&quot;:&quot;Nurbo Kusmagul&quot;,&quot;bio&quot;:&quot;Mastering Algorithms &amp; Data Structures | Follow for Clear, Fun, and Practical Tech Knowledge&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ae212a87-4f50-4e9a-8570-9022fc4a1836_1740x1740.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-09-18T20:44:03.224Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8ee4cc0-f619-45b1-8add-3f56e6c5b49c_2000x1334.jpeg&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://blog.faangshui.com/p/before-leetcode&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:149072585,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:15,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Faangshui - Algorithms, Data Structures &amp; Coding Interviews&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F895e7a9e-879c-4fcf-a598-b65ecf31a271_1280x1280.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>For more advanced learners, you will naturally strengthen your APSS when solving more and more problems from Leetcode or elsewhere.</p><div><hr></div><h2>Other Problems to Test Your APSS</h2><p>Here are a few other fun problems that should be suitable for any level:</p><h3><strong>1. Print a Diamond Pattern</strong></h3><p>Given a positive odd integer <strong>n</strong>, print a diamond pattern made of asterisks (*) where the widest point is <strong>n</strong> asterisks wide.</p><p><strong>Input:</strong> <code>n = 5</code></p><p><strong>Output:</strong></p><pre><code>  *
 ***
*****
 ***
  *</code></pre><div><hr></div><h3><strong>2. Increasing Staircase Pattern</strong></h3><p>Given an integer <strong>n</strong>, print a right-justified staircase of numbers that increases with each step. The last row should contain the numbers from 1 to <strong>n</strong>.</p><p>For <code>n = 5</code>, the output would be:</p><pre><code>        1
      1 2
    1 2 3
  1 2 3 4
1 2 3 4 5</code></pre><div><hr></div><h3><strong>3. Rearrange Array to Move All Zeros to the End</strong></h3><p><strong>Problem Statement:</strong></p><p>Given a 1D array of integers, rearrange it in-place so that all zeroes are moved to the end while maintaining the order of non-zero elements.</p><p><strong>Example:</strong> For <code>[0, 1, 0, 3, 12]</code>, the output should be <code>[1, 3, 12, 0, 0]</code>.</p><div><hr></div><h2>Next Steps</h2><p>Only after strengthening your APSS do I recommend gradually moving on to classic algorithms and data structures and precompiled lists. With a solid foundation, you'll find it easier to understand and implement more complex concepts.</p><p>Remember, it's not about how many problems you've memorized but how well you can apply fundamental concepts to solve new problems.</p><div><hr></div><p><strong>Stay curious and happy coding!</strong></p><p><strong>Nurbo</strong></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.faangshui.com/subscribe?"><span>Subscribe now</span></a></p><h2>I'm Accepting New Mentees!</h2><p>Are you looking for a mentor to guide you and keep you accountable on your tech interview preparation journey? I'm here to help.</p><p>I'm opening up a few spots for motivated individuals who would benefit from weekly one-on-one mentorship sessions. Together, we'll:</p><ul><li><p><strong>Develop a personalized study plan</strong></p></li><li><p><strong>Master problem-solving techniques</strong></p></li><li><p><strong>Build confidence for your interviews</strong></p></li></ul><p><strong>Ready to take your preparation to the next level?</strong> Book a <strong>free introductory session</strong> with me <a href="https://link.faangshui.com/book">here</a>.</p>]]></content:encoded></item><item><title><![CDATA[How To Boost Your Interview Results by 20%]]></title><description><![CDATA[And It's Free Too]]></description><link>https://blog.faangshui.com/p/boost-your-interview-results-by-20</link><guid isPermaLink="false">https://blog.faangshui.com/p/boost-your-interview-results-by-20</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Thu, 24 Oct 2024 18:37:28 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/5d961cf9-a4b2-4a47-92df-02364ba8c7e6_626x626.avif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>There are times when it's clear that an interview didn't go as planned. Perhaps you struggled to solve the coding problem, or your system design didn't handle the requirements that well. In such cases, it's understandable if you don't receive an offer.</p><p>However, there are also situations where you performed reasonably well, but you're unsure whether you passed the interviews. Often, your interviewers might be on the fence about extending an offer as well.</p><p>In these borderline cases, there's a way to tip the scales in your favor, and it has nothing to do with your technical skills. It's all about <strong>showing enthusiasm</strong>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.faangshui.com/subscribe?"><span>Subscribe now</span></a></p><h2>Why Enthusiasm Matters</h2><p>Enthusiasm can make a significant difference in the hiring decision. It demonstrates your genuine interest in the company and the role, which can be a deciding factor when interviewers are uncertain. Showing that you're eager to join the team and contribute positively can set you apart from other candidates with similar technical abilities.</p><p>I've personally sat on a few hiring committees where perhaps one or two interviews didn't go perfectly for a candidate. However, because the candidate showed so much enthusiasm for the company, there were advocates who would say that this person would be a great fit for the team. Others would agree, and we ended up extending an offer. Their passion and eagerness to contribute made a lasting impression that outweighed minor technical shortcomings.</p><p>Enthusiasm signals to the interviewers that you are not just looking for any job but are specifically interested in contributing to their company's success. This can make them more willing to invest in you, even if there are areas where you need to grow.</p><h2>Ways to Show Your Enthusiasm</h2><p>You don't have to fake passion for the company or offer excessive praise. Showing enthusiasm means demonstrating that you care and are genuinely interested in what the company does. You prove your enthusiasm by doing your homework and learning about the company&#8217;s business. Your interest will naturally shine through during your conversations with interviewers.</p><p>Here are some effective ways to convey your enthusiasm during the interview process:</p><h3>1. <strong>Research the Company</strong></h3><ul><li><p><strong>Understand the Mission and Values</strong>: Familiarize yourself with the company's mission statement and core values. Reflect on how they align with your personal and professional goals.</p></li><li><p><strong>Know the Products and Services</strong>: Explore the company's products or services. If possible, use them yourself to gain firsthand experience.</p></li><li><p><strong>Read the Engineering Blog</strong>: If the company has an engineering blog, read recent posts. This can give you insight into their development processes and current projects.</p></li></ul><h3>2. <strong>Engage with the Industry</strong></h3><ul><li><p><strong>Stay Informed</strong>: Keep up with the latest trends and developments in the industry. </p></li><li><p><strong>Understand Industry Challenges</strong>: Discuss common challenges in the industry and how you might address them, demonstrating critical thinking and initiative.</p></li></ul><h3>3. <strong>Prepare Thoughtful Questions</strong></h3><ul><li><p><strong>Ask Insightful Questions</strong>: Prepare questions that show deep interest, such as inquiries about upcoming projects, team dynamics, or company growth plans.</p></li><li><p><strong>Avoid Questions About Tech Stack:</strong> These questions don&#8217;t tell much about you or the company. You shouldn&#8217;t be joining a company for the tools they use, so don&#8217;t waste the opportunity to ask meaningful questions.</p></li><li><p><strong>Avoid Generic Questions</strong>: Steer clear of questions that could be easily answered by reading the company's website.</p></li></ul><h2>Summing up</h2><p>While technical skills are crucial, enthusiasm and cultural fit can play a significant role in the hiring decision, especially when interview performance is borderline. By demonstrating genuine interest and aligning yourself with the company's mission and values, you can boost your chances of receiving an offer.</p><p>Remember, showing enthusiasm doesn't cost anything, but it can make all the difference.</p><p>Stay curious and happy coding!</p><p>Nurbo</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Faangshui! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>I'm Accepting New Mentees!</h2><p>Are you looking for a mentor to guide you and keep you accountable on your tech interview preparation journey? I'm here to help.</p><p>I'm opening up a few spots for motivated individuals who would benefit from weekly one-on-one mentorship sessions. Together, we'll:</p><ul><li><p><strong>Develop a personalized study plan</strong></p></li><li><p><strong>Master problem-solving techniques</strong></p></li><li><p><strong>Build confidence for your interviews</strong></p></li></ul><p><strong>Ready to take your preparation to the next level?</strong> Book a <strong>free introductory session</strong> with me <a href="https://link.faangshui.com/book">here</a>.</p>]]></content:encoded></item><item><title><![CDATA[What's Your Opening Strategy?]]></title><description><![CDATA[Mastering the First 15 Minutes of Your Coding Interview]]></description><link>https://blog.faangshui.com/p/whats-your-opening-strategy</link><guid isPermaLink="false">https://blog.faangshui.com/p/whats-your-opening-strategy</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Mon, 21 Oct 2024 14:27:49 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/5bced188-b491-4308-96b0-9b53a6a359a5_1200x800.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The most important part of a coding interview is the <strong>first 15 minutes</strong>. These initial moments can make or break your interview. This is the time you spend understanding the problem and fleshing out your approach. It's also when your interviewer forms their first impression of you.</p><p>Many candidates approach this phase without a clear plan. However, you can significantly improve your odds of success by adopting a structured approach.</p><p>I call this structure <strong>the opening strategy</strong>.</p><p>Just like in chess, where the opening strategy sets the direction of the game, your interview opening strategy sets the tone for the rest of your interview.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.faangshui.com/subscribe?"><span>Subscribe now</span></a></p><h2>The Ideal Opening Strategy for Your Coding Interview</h2><h4><strong>Minutes 1&#8211;3: Read the Problem Carefully</strong></h4><ul><li><p>Read the problem statement thoroughly.</p></li><li><p>Reread important parts to ensure complete comprehension.</p></li></ul><h4><strong>Minutes 3&#8211;5: Analyze Inputs and Outputs</strong></h4><ul><li><p>Examine the input and output formats.</p></li><li><p>Draw diagrams on paper&#8212;arrays, trees, graphs, etc. Make sure to have your pen and paper ready for this.</p></li><li><p>Check the role of each parameter.</p></li><li><p>Verify why the sample output corresponds to the given input.</p></li><li><p>Visualize extensively: data structures, data flow, and the actions applied to the data.</p></li></ul><h4><strong>Minutes 1&#8211;5: Ask Clarifying Questions</strong></h4><ul><li><p>At any point during this time, ask the interviewer clarifying questions.</p></li><li><p>Aim to ask at least two meaningful questions.</p></li><li><p>Avoid jumping into solutions; suppress thoughts about the approach or implementation for now.</p></li></ul><h4><strong>Minutes 5&#8211;7: Create Your Own Examples</strong></h4><ul><li><p>Develop one or two examples to verify your understanding.</p></li><li><p>Confirm these examples with the interviewer.</p></li><li><p>This will help in identifying a viable approach.</p></li></ul><p>Tips for Creating Examples:</p><ul><li><p>Don't make them too simple or too complex; ensure they have substance.</p></li><li><p>Copy and modify the sample input provided if the input is too complex to write from scratch (i.e. matrix, graphs, etc.).</p></li><li><p>Consider changing some parameters if there are several for a quick new example.</p></li><li><p>Avoid focusing on edge cases at this point.</p></li></ul><div><hr></div><p><strong>The goal of the first part of your opening strategy is to fully understand the problem.</strong> Understanding the problem is half the solution. If you don't fully grasp what's being asked, it's unproductive to start thinking about solutions. There should be no trace of doubt in your understanding.</p><div><hr></div><h4><strong>Minutes 7&#8211;15: Identify an Optimal Approach</strong></h4><p>Now that you thoroughly understand the problem and have worked through examples, it's time to devise an approach.</p><ul><li><p>Use your drawings, examples, and prior experience with similar problems to guide you.</p></li><li><p>Don't be overly cautious; explore any algorithms or data structures that come to mind.</p></li><li><p>Discuss your thought process with the interviewer.</p></li><li><p>Aim to find the most efficient solution before diving into coding.</p></li></ul><h4><strong>Minutes 15&#8211;40: Implement Your Solution</strong></h4><p>This phase isn't part of the opening strategy, but it greatly benefits from it. If you've executed your opening strategy effectively, this part&#8212;coding your solution&#8212;should be more straightforward.</p><div><hr></div><h2>Why This Opening Strategy Works</h2><ul><li><p><strong>Avoids Misunderstandings:</strong> Early clarification prevents wasted time on incorrect solutions.</p></li><li><p><strong>Builds Confidence:</strong> A structured plan reduces anxiety and boosts confidence.</p></li><li><p><strong>Brings Closer to The Solution:</strong> Focus on understanding and examples gets you to the solution faster.</p></li><li><p><strong>First Impressions Matter:</strong> Demonstrating a methodical approach impresses interviewers.</p></li><li><p><strong>Highlights Communication Skills:</strong> Engaging with the interviewer shows collaboration and problem-solving abilities.</p></li></ul><p>Approaching your coding interviews with a well-defined opening strategy can significantly enhance your performance. By dedicating the first 15 minutes to understanding the problem thoroughly and outlining an optimal approach, you set yourself up for success in the rest of the interview.</p><p>Stay curious and happy coding!</p><p>Nurbo</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Hey! Why not subscribe for free to receive new posts and support my work!</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>I'm Accepting New Mentees!</h2><p>Are you looking for a mentor to guide you and keep you accountable on your tech interview preparation journey? I'm here to help.</p><p>I'm opening up a few spots for motivated individuals who would benefit from weekly one-on-one mentorship sessions. Together, we'll:</p><ul><li><p><strong>Develop a personalized study plan</strong></p></li><li><p><strong>Master problem-solving techniques</strong></p></li><li><p><strong>Build confidence for your interviews</strong></p></li></ul><p><strong>Ready to take your preparation to the next level?</strong> Book a <strong>free introductory session</strong> with me <a href="https://link.faangshui.com/book">here</a>. </p><p></p>]]></content:encoded></item><item><title><![CDATA[My Heaps Don't Lie]]></title><description><![CDATA[Or How To Identify and Solve Any Priority Queue Problem]]></description><link>https://blog.faangshui.com/p/my-heaps-dont-lie</link><guid isPermaLink="false">https://blog.faangshui.com/p/my-heaps-dont-lie</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Thu, 17 Oct 2024 18:11:35 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/b1ac402c-e2fd-4b1a-8422-bef28c54d7ff_1307x803.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Priority queues and heaps are fundamental data structures that frequently appear in coding interviews. They might seem daunting at first, but once you understand how they work and how to apply them, you'll feel lucky to receive a priority queue interview question because of how easy it is to solve them.</p><p>In this issue, we&#8217;ll break down the essentials of priority queues and heaps, explore common problem patterns, and provide a step-by-step approach to help you tackle any heap-related problem.</p><div><hr></div><h2>Priority Queues vs Heaps</h2><p>Let&#8217;s first clarify the difference between Priority Queues and Heaps.</p><p>tldr: Priority Queue is an idea of a data structure and Heaps are a concrete data structure that is the most common implementation of a Priority Queue.</p><h3>What Is a Priority Queue?</h3><p>A <strong>priority queue</strong> is an abstract data type similar to a regular queue or stack, but with an additional feature: each element has a "priority" associated with it. In a priority queue, elements are served based on their priority, not just their insertion order.</p><h3>What Is a Heap?</h3><p>A <strong>heap</strong> is a specialized tree-based data structure that satisfies the heap property:</p><ul><li><p><strong>Max-Heap</strong>: In a max-heap, for any given node <code>C</code>, the value of <code>C</code> is less than or equal to the value of its parent <code>P</code>. The highest value is at the root.</p></li><li><p><strong>Min-Heap</strong>: In a min-heap, the value of <code>C</code> is greater than or equal to the value of its parent <code>P</code>. The lowest value is at the root.</p></li></ul><p>Heaps are commonly used to implement priority queues because they allow for efficient retrieval and modification of the highest or lowest priority element. In practice, the two terms are often used interchangeably, but not by you - because now you know the difference.</p><div><hr></div><h2>When to Use Heaps: The Key Indicator</h2><p>One of the biggest giveaways that heaps are appropriate is when the problem involves <strong>dynamic or streaming data</strong>. Heaps allow you to process incoming data as it arrives and provide the ability to query for the maximum or minimum value at any time. When the data is static, it is often sufficient to use a sorting algorithm. However, for <strong>dynamic datasets</strong> where elements are continually added or removed, heaps offer efficient O(log n) insertion and deletion operations, making them ideal for maintaining order in real-time.</p><div><hr></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.faangshui.com/subscribe?"><span>Subscribe now</span></a></p><h2>Common Problem Patterns Involving Heaps</h2><h3>1. <strong>Kth Largest/Smallest Element</strong></h3><p><strong>Scenario</strong>: If the problem asks for the Kth largest or smallest element in a collection, heaps are ideal since they allow efficient insertion and extraction of the minimum or maximum element.</p><p><strong>Example</strong>: <em>"Find the Kth largest number in a stream."</em></p><p><strong>Approach</strong>:</p><ul><li><p><strong>Dynamic Data</strong>: Since the data may be continuously updated, a heap allows you to maintain the K largest elements efficiently.</p></li><li><p><strong>Implementation</strong>: Use a min-heap of size <code>k</code> to keep track of the top <code>k</code> largest elements in real-time.</p></li></ul><p><strong>LeetCode Example</strong>: 703. Kth Largest Element in a Stream</p><h3>2. <strong>Merging or Sorting Multiple Lists</strong></h3><p><strong>Scenario</strong>: Problems that require merging multiple sorted lists or arrays can often be optimized using a heap. This allows you to keep track of the smallest (or largest) element from each list and merge efficiently.</p><p><strong>Example</strong>: <em>"Merge k sorted linked lists into one sorted list."</em></p><p><strong>Approach</strong>:</p><ul><li><p><strong>Dynamic Selection</strong>: A heap helps you dynamically select the next smallest element among the heads of the lists.</p></li><li><p><strong>Implementation</strong>: Use a min-heap to store the current smallest element from each list.</p></li></ul><p><strong>LeetCode Example</strong>: 23. Merge k Sorted Lists</p><h3>3. <strong>Frequent Elements</strong></h3><p><strong>Scenario</strong>: If you're asked to find the top K most frequent elements or similar problems involving frequency and ranking, heaps can be used to efficiently maintain the top K elements as you process the data.</p><p><strong>Example</strong>: <em>"Find the top K most frequent words in a list of words."</em></p><p><strong>Approach</strong>:</p><ul><li><p><strong>Dynamic Counting</strong>: While the data may be static, heaps allow for efficient retrieval of the top frequencies without sorting the entire frequency map.</p></li><li><p><strong>Implementation</strong>: Use a min-heap of size <code>k</code> to keep track of the top K elements based on frequency.</p></li></ul><p><strong>LeetCode Example</strong>: 692. Top K Frequent Words</p><h3>4. <strong>Dynamic Minimum/Maximum</strong></h3><p><strong>Scenario</strong>: Any problem where you need to repeatedly access the minimum or maximum element in a dynamic dataset (inserting and removing elements) is a strong indicator for using a heap.</p><p><strong>Example</strong>: <em>"Design a data structure that supports inserting numbers and retrieving the maximum number at any time."</em></p><p><strong>Approach</strong>:</p><ul><li><p><strong>Dynamic Data</strong>: As elements are added or removed, the heap maintains the ordering.</p></li><li><p><strong>Implementation</strong>: Use a max-heap to maintain the maximum element.</p></li></ul><p><strong>LeetCode Example</strong>: 716. Max Stack</p><h3>5. <strong>Scheduling or Task Execution</strong></h3><p><strong>Scenario</strong>: If the problem involves scheduling tasks based on priorities or deadlines, a priority queue can help efficiently pick the next task to execute based on priority.</p><p><strong>Example</strong>: <em>"Given tasks with deadlines and durations, find the optimal schedule to maximize completed tasks."</em></p><p><strong>Approach</strong>:</p><ul><li><p><strong>Dynamic Selection</strong>: Tasks may be added or priorities may change; a heap allows for efficient retrieval of the highest priority task.</p></li><li><p><strong>Implementation</strong>: Use a heap to select the next task based on priority criteria (e.g., earliest deadline).</p></li></ul><p><strong>LeetCode Example</strong>: 621. Task Scheduler</p><h3>6. <strong>Sliding Window Problems</strong></h3><p><strong>Scenario</strong>: Problems where you need to track the maximum or minimum value in a sliding window (e.g., "find the maximum in each sliding window of size K") often benefit from heaps to efficiently maintain the range's top elements.</p><p><strong>Example</strong>: <em>"Find the maximum number in each sliding window of size K in an array."</em></p><p><strong>Approach</strong>:</p><ul><li><p><strong>Dynamic Window</strong>: As the window slides, elements enter and exit the window dynamically.</p></li><li><p><strong>Implementation</strong>: Use a max-heap to keep track of the maximum element in the current window, taking care to discard elements that are no longer in the window.</p></li></ul><p><strong>LeetCode Example</strong>: 239. Sliding Window Maximum</p><h3>7. <strong>Shortest Path or Minimum Spanning Tree</strong></h3><p><strong>Scenario</strong>: Graph-related problems like Dijkstra&#8217;s algorithm (for shortest paths) or Prim&#8217;s algorithm (for minimum spanning trees) make heavy use of priority queues to efficiently find the next node with the smallest cost.</p><p><strong>Example</strong>: <em>"Find the shortest path from a source node to all other nodes in a weighted graph."</em></p><p><strong>Approach</strong>:</p><ul><li><p><strong>Dynamic Edge Weights</strong>: The priority queue (min-heap) allows for efficient selection of the next node with the smallest tentative distance.</p></li><li><p><strong>Implementation</strong>: Use a min-heap to store nodes with their current shortest distance estimates.</p></li></ul><p><strong>LeetCode Example</strong>: 743. Network Delay Time</p><h3>8. <strong>Order Statistics</strong></h3><p><strong>Scenario</strong>: When the problem requires maintaining some sort of running order statistic, such as finding the median in a dynamic stream of numbers.</p><p><strong>Example</strong>: <em>"Design a data structure that supports adding numbers and finding the median."</em></p><p><strong>Approach</strong>:</p><ul><li><p><strong>Dynamic Median</strong>: As new numbers come in, the median can change.</p></li><li><p><strong>Implementation</strong>: Use two heaps&#8212;a max-heap for the lower half and a min-heap for the upper half&#8212;to maintain balance and efficiently compute the median.</p></li></ul><p><strong>LeetCode Example</strong>: 295. Find Median from Data Stream</p><div><hr></div><h2>Step-by-Step Approach to Solving Heap Problems</h2><h4><strong>Step 1: Understand the Problem Thoroughly</strong></h4><ol><li><p><strong>Read Carefully</strong>: Ensure you understand what the problem is asking.</p></li><li><p><strong>Identify Clues</strong>: Look for scenarios involving dynamic or streaming data, need for frequent access to min/max elements, or maintaining top K elements.</p></li></ol><h4><strong>Step 2: Determine If a Heap Is Appropriate</strong></h4><ol><li><p><strong>Dynamic Data</strong>: If the data is dynamic (elements are added or removed over time), a heap is likely appropriate.</p></li><li><p><strong>Real-Time Queries</strong>: If you need to query for the max or min at any time during data updates, consider using a heap.</p></li><li><p><strong>Static Data</strong>: If the data is static and all you need is to find min/max or sort once, a sorting algorithm may suffice.</p></li></ol><h4><strong>Step 3: Choose the Right Type of Heap</strong></h4><ol><li><p><strong>Min-Heap vs. Max-Heap</strong>:</p><ul><li><p><strong>Min-Heap</strong>: Access the smallest element.</p></li><li><p><strong>Max-Heap</strong>: Access the largest element.</p></li></ul></li><li><p><strong>Combination</strong>:</p><ul><li><p>Some problems require both (e.g., maintaining medians).</p></li></ul></li></ol><h4><strong>Step 4: Decide on the Programming Language and Libraries</strong></h4><ul><li><p><strong>Python</strong>: Use the <code>heapq</code> module (min-heap). For max-heap, invert the values.</p></li><li><p><strong>Java</strong>: Use <code>PriorityQueue</code> class. For max-heap, provide a custom comparator.</p></li><li><p><strong>C++</strong>: Use <code>priority_queue</code> from STL. Default is max-heap.</p></li><li><p><strong>Ruby</strong>: Unfortunately heaps are not available in the standard Ruby libraries. Some platforms like Leetcode have the <code>algorithms</code> gem readily available but there is no guarantee that it will be available for you during your interview. I personally would make an assumption that there is some MaxHeap/MinHeap data structure available and then will implement it myself at the end if time permits.</p></li></ul><h4><strong>Step 5: Implement the Solution</strong></h4><ol><li><p><strong>Initialize the Heap</strong>: Build the heap with initial elements if any.</p></li><li><p><strong>Perform Heap Operations</strong>:</p><ul><li><p><strong>Insertion</strong>: Add elements as they come.</p></li><li><p><strong>Deletion</strong>: Remove elements based on problem logic.</p></li><li><p><strong>Peek</strong>: Access the top element without removing it.</p></li></ul></li></ol><div><hr></div><h2>Tips and Tricks</h2><h3><strong>1. Dynamic vs. Static Data</strong></h3><p><strong>Dynamic Data</strong>: When dealing with data that changes over time (insertions, deletions), heaps provide efficient O(log n) operations for maintaining order.</p><p><strong>Static Data</strong>: If the dataset doesn't change, sorting algorithms (O(n log n)) may be more straightforward and sometimes more efficient for one-time processing.</p><h3><strong>2. Be Mindful of Element Indices</strong></h3><p>In problems like sliding window maximum, store indices along with values to know when to discard elements that are no longer within the window.</p><h3><strong>3. Simulating Max-Heap in Min-Heap Languages</strong></h3><p>In languages like Python, which only provide a min-heap, invert the values to simulate a max-heap.</p><pre><code>heapq.heappush(max_heap, -num)</code></pre><h3><strong>4. Combine Heaps with Other Data Structures</strong></h3><p>Sometimes, heaps alone may not suffice. Combining them with hash maps, deques, or other data structures can solve more complex problems.</p><h3><strong>5. Practice Standard Problems</strong></h3><p>Familiarize yourself with classic heap problems to recognize patterns quickly.</p><div><hr></div><h2>Summing Up</h2><p>Mastering priority queues and heaps equips you with a powerful tool to efficiently solve a variety of problems that involve ordering, scheduling, and dynamically tracking extrema in datasets. These types of problems are quite frequent in coding interviews at top tech companies. Make sure to practice the problems referenced above as well as other problems tagged as &#8220;Heap&#8221;.</p><p><strong>Stay curious and happy coding!</strong></p><p><strong>Nurbo</strong></p><div><hr></div><h2>I'm Accepting New Mentees!</h2><p>Are you looking for a mentor to guide you and keep you accountable on your tech interview preparation journey? I'm here to help.</p><p>I'm opening up a few spots for motivated individuals who would benefit from weekly one-on-one mentorship sessions. Together, we'll:</p><ul><li><p><strong>Develop a personalized study plan</strong></p></li><li><p><strong>Master problem-solving techniques</strong></p></li><li><p><strong>Build confidence for your interviews</strong></p></li></ul><p><strong>Ready to take your preparation to the next level?</strong> Book a <strong>free introductory session</strong> with me <a href="https://link.faangshui.com/book">here</a>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Subscribe for free and receive new insights from me every week day!</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[The Missing Book of DSA]]></title><description><![CDATA[What I'm Working On and Why]]></description><link>https://blog.faangshui.com/p/the-missing-book-of-dsa</link><guid isPermaLink="false">https://blog.faangshui.com/p/the-missing-book-of-dsa</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Wed, 16 Oct 2024 16:35:13 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/81a78b7a-66fd-4371-b253-233a95eac18d_460x510.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I've briefly mentioned in one of my previous newsletters that I'm working on a book on coding challenges. Today, I want to share with you why I'm working on this book and what it's all about.</p><h2>The Search for the Missing Piece</h2><p>Over the past 20 years, I've been deeply involved in algorithmic coding challenges. Two decades ago, I started participating in competitive programming competitions, and in recent years, I've been mentoring people to improve their coding interview skills. Throughout this journey, I've used all kinds of resources to learn and teach algorithmic problem-solving.</p><p>While there are great problem archives like Leetcode or Codeforces, and excellent textbooks like <em>Introduction to Algorithms</em> (CLRS), I've found that there's no single unified resource that teaches the art of solving coding challenges in a holistic way. I wanted a resource that provides just enough theory and lots of relevant exercises, tailored to the needs of both coding interviews and competitive programming. With this book, I hope to bridge that gap.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.faangshui.com/subscribe?"><span>Subscribe now</span></a></p><h2>The Series</h2><p>The book I'm working on, currently code-named <strong>Initiation</strong>, is actually the first in a series of eight books. The series is designed to take someone who has never encountered a coding challenge (but can code) all the way to being FAANG interview-ready.</p><p><strong>Initiation</strong> is targeted at beginners and will cover fundamental topics such as nested loops, array indexing, hash tables, and time and space complexities&#8212;all within the context of coding challenges.</p><p>Here are a few features of the book that I'm particularly excited about:</p><ul><li><p><strong>A Quest-Like Storyline</strong>: Set in the fictional School of Faangshui, you'll learn as an apprentice under Master Hashi, the legendary Grandmaster of Faangshui.</p></li><li><p><strong>Gradual Difficulty Build-Up</strong>: The topics and exercises are structured to progressively increase in difficulty, helping you build your skills step by step.</p></li><li><p><strong>Interactive Learning</strong>: The book provides just enough theory, accompanied by inline exercises that reinforce the concepts.</p></li><li><p><strong>Integrated Coding Platform</strong>: A built-in code editor and online judge offer immediate feedback on your code submissions.</p></li><li><p><strong>AI-Powered Feedback</strong>: Receive personalized feedback from Master Hashi himself, powered by AI, to help you improve your solutions.</p></li></ul><p>The goal of the series is to make learning algorithmic problem-solving fun and interactive.</p><h2>The Work Ahead</h2><p>My original plan was to have an alpha version ready by the end of this month. I'm not sure if I'll make it in time, but here's what I've accomplished so far:</p><ul><li><p><strong>Platform Development</strong>: I have a basic version of the platform ready, complete with a built-in online judge and AI-powered feedback from Master Hashi.</p></li><li><p><strong>Content Creation</strong>: I'm making steady progress on the content. So far, I have many pieces of text that need to be organized and connected.</p></li><li><p><strong>Balancing Story and Teaching</strong>: I haven't yet figured out how to balance the storyline with the instructional material. My hope is to test this with alpha readers and adjust based on their feedback.</p></li><li><p><strong>Attention to Detail</strong>: The more I work on the project, the more details I realize need to be addressed. It's a challenging but rewarding process.</p></li></ul><h2>Looking for Alpha Readers</h2><p>There will be rough edges to smooth out and bugs to fix, and that's where you come in. If you're interested in being among the first to read the book and test the platform, please let me know by filling out <a href="https://forms.gle/vB9mnTWHvnnH1hMH9">this form</a>. Your feedback will be invaluable, and I would greatly appreciate your help!</p><p><strong>Stay curious and happy coding!</strong></p><p><strong>Nurbo</strong></p><p></p><div><hr></div><h2>I'm Accepting New Mentees!</h2><p>Are you looking for a mentor to guide you and keep you accountable on your tech interview preparation journey? I'm here to help.</p><p>I'm opening up a few spots for motivated individuals who would benefit from weekly one-on-one mentorship sessions. Together, we'll:</p><ul><li><p><strong>Develop a personalized study plan</strong></p></li><li><p><strong>Master problem-solving techniques</strong></p></li><li><p><strong>Build confidence for your interviews</strong></p></li></ul><p><strong>Ready to take your preparation to the next level?</strong> Book a <strong>free introductory session</strong> with me <a href="https://link.faangshui.com/book">here</a>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Faangshui! Subscribe for free to receive new posts every week day.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Dynamic Programming: The Story Behind Its Name]]></title><description><![CDATA[The Curious Origin of a Misleading Term]]></description><link>https://blog.faangshui.com/p/dynamic-programming-the-story-behind</link><guid isPermaLink="false">https://blog.faangshui.com/p/dynamic-programming-the-story-behind</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Mon, 14 Oct 2024 18:42:29 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/41575c17-bb0f-45c3-958d-e1e7fd7ddd08_402x600.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Arguably, one of the most feared topics in technical interviews for software engineers is <strong>dynamic programming</strong> (DP). The technique itself can be elusive&#8212;it's hard to learn on your own, and it's rarely taught well. Many struggle not only with applying DP but also with understanding what the term actually means.</p><p>When I was kid, I dreaded encountering a dynamic programming problem in coding competitions. While I knew the theory and could solve classic problems, I often couldn't apply my knowledge to new DP problems where the solution wasn't immediately obvious.</p><p>But what confused me even more than the topic itself was the name <strong>dynamic programming</strong>. In what sense is it "dynamic"? Why "programming"? Aren't we always programming when we code? In a field where precise naming is important, this term feels generic and doesn't offer clues about the concept.</p><p>It turns out, that was intentional.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.faangshui.com/subscribe?"><span>Subscribe now</span></a></p><h3>The Origin Story</h3><p>Richard Bellman, the mathematician who developed dynamic programming in the 1950s, shared an interesting anecdote in his autobiography <em>"Eye of the Hurricane"</em>. At the time, Bellman was working at RAND Corporation, and the word "research" was frowned upon by the secretary of defense, who controlled the funding. Mathematical research, in particular, was under scrutiny.</p><p>To secure funding without attracting negative attention, Bellman chose the term <strong>"dynamic programming"</strong> to describe his work. The word "dynamic" implied action and progress, while "programming" was associated with planning and decision-making, not necessarily coding as we think of it today. The term was deliberately vague and non-threatening to the bureaucrats who might cut his budget.</p><p>Thanks to his ingenuity, Bellman was able to continue his research, leading to the development of dynamic programming and the Bellman equation. While the name doesn't make the concept any clearer, it served its purpose at the time&#8212;a small price to pay for such a valuable contribution to mathematics and computer science.</p><h3>Embracing Dynamic Programming Today</h3><p>Even though I haven't encountered a dynamic programming problem in a real-world project or interview yet, I still find the topic fascinating. I keep my DP problem-solving skills sharp and have largely overcome my earlier apprehension.</p><p>In a world as dynamic as ours, it's hard to predict when you'll need to "dynamically program" your way out of a problem. Understanding the history behind the term adds a layer of appreciation for the technique and reminds us that sometimes, names have stories that reflect the challenges of their time.</p><p><strong>Stay curious and happy coding!</strong></p><p><strong>Nurbo</strong></p><div><hr></div><h2>I'm Accepting New Mentees!</h2><p>Are you looking for a mentor to guide you and keep you accountable on your tech interview preparation journey? I'm here to help.</p><p>I'm opening up a few spots for motivated individuals who would benefit from weekly one-on-one mentorship sessions. Together, we'll:</p><ul><li><p><strong>Develop a personalized study plan</strong></p></li><li><p><strong>Master problem-solving techniques</strong></p></li><li><p><strong>Build confidence for your interviews</strong></p></li></ul><p><strong>Ready to take your preparation to the next level?</strong> Book a <strong>free introductory session</strong> with me <a href="https://link.faangshui.com/book">here</a>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Faangshui! Subscribe for free to receive new posts every week day.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[What Language to Use During Your Interview]]></title><description><![CDATA[It's Not Python]]></description><link>https://blog.faangshui.com/p/what-language-to-use-during-your</link><guid isPermaLink="false">https://blog.faangshui.com/p/what-language-to-use-during-your</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Fri, 11 Oct 2024 16:24:04 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/e8151714-c183-4944-95c6-1a196635ba66_2560x1766.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>What programming language to use during your interview?</p><p>The answer to this question is simple: <strong>use the language you are most familiar with</strong>. Do not blindly default to Python unless that's the language you use most often.</p><div><hr></div><h2>Here's Why</h2><p>During a coding interview, you want to impress your interviewers&#8212;not just by solving the problem, but also by demonstrating proficiency and fluency in the language you choose. Your choice reflects your technical abilities and your approach to work. In fact, many companies include "coding fluency" as one of the assessment criteria during interviews.</p><p>Using a language you're deeply familiar with allows you to:</p><ul><li><p><strong>Write code more efficiently</strong>: You can focus on solving the problem rather than wrestling with syntax.</p></li><li><p><strong>Demonstrate best practices</strong>: Show your understanding of the language's idioms and nuances.</p></li><li><p><strong>Handle edge cases confidently</strong>: You're less likely to be tripped up by unfamiliar behavior or gotchas.</p></li></ul><div><hr></div><h2>When to Use Python</h2><p>There are only a few reasons to use Python during your interviews:</p><ul><li><p><strong>It's the language you use at work</strong>: If Python is your primary language professionally, by all means, use it.</p></li><li><p><strong>You don't have a clear go-to language</strong>: If you're in college or have just graduated and haven't specialized in a particular language, Python is a good choice due to its readability and ease of use.</p></li><li><p><strong>Your only other language is Assembly</strong>.</p></li></ul><div><hr></div><h2>Personal Experience</h2><p>The last time I changed jobs and interviewed with several companies, I used <strong>Java</strong>, and it was perfectly fine. At the time, I worked at Amazon and wrote most of my code in Java, so it made sense to use it during interviews.</p><p>If I were to interview today, I would use <strong>Ruby</strong>, because that's the language I used daily at my last job at Chime and also for my side projects.</p><p>Could I write the code in Python? Probably, yes. But I don't know all the intricacies of Python to fully showcase my coding skills. Even though I'm familiar with Python's idioms, there could be a problem where I might need parts of Python that I haven't used as much.</p><p>In fact, during one of my interviews in my last job-hunting cycle, I needed advanced object-oriented programming (OOP) skills as well as data structures and algorithms (DSA) knowledge to fully solve the given problem. Had I used anything other than Java at the time, I might have failed that interview.</p><div><hr></div><h2>Why Do I Use Python in My Newsletter?</h2><p>You may have noticed that much of my content includes examples in Python and often references Python's implementation of different functions and data structures. The reason is simple:</p><ul><li><p><strong>Python is a common default</strong>: Many people choose Python when preparing for coding interviews due to its simplicity and readability.</p></li><li><p><strong>Widespread familiarity</strong>: Even if readers prefer a different language, they're often familiar with Python syntax, making the examples accessible.</p></li><li><p><strong>Focus on concepts</strong>: Using a universally understood language helps convey ideas without getting bogged down in language-specific details.</p></li></ul><div><hr></div><p><strong>Bottom Line</strong>: Use the programming language you are most comfortable with during your interviews. It allows you to demonstrate your true potential and makes the problem-solving process smoother. While Python is a fantastic language, it's not the automatic choice for everyone&#8212;and that's perfectly okay.</p><div><hr></div><h2>I'm Accepting New Mentees!</h2><p>Are you looking for a mentor to guide you and keep you accountable on your tech interview preparation journey? I'm here to help.</p><p>I'm opening up a few spots for motivated individuals who would benefit from weekly one-on-one mentorship sessions. Together, we'll:</p><ul><li><p><strong>Develop a personalized study plan</strong></p></li><li><p><strong>Master problem-solving techniques</strong></p></li><li><p><strong>Build confidence for your interviews</strong></p></li></ul><p><strong>Ready to take your preparation to the next level?</strong> Book a <strong>free introductory session</strong> with me <a href="https://link.faangshui.com/book">here</a>.</p><p></p><p><strong>Stay curious and happy coding!</strong></p><p><strong>Nurbo</strong></p>]]></content:encoded></item><item><title><![CDATA[Not All Keys Fit: Python's Dictionary Limitations]]></title><description><![CDATA[Why Some Objects Can't Be Dictionary Keys and How to Work Around It]]></description><link>https://blog.faangshui.com/p/not-all-keys-fit-pythons-dictionary</link><guid isPermaLink="false">https://blog.faangshui.com/p/not-all-keys-fit-pythons-dictionary</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Thu, 10 Oct 2024 16:27:33 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/80132170-50b7-479f-a600-31834a6d5752_1200x800.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In coding problems, you might want to associate data with complex structures like lists or other dictionaries. While languages like Ruby or PHP allow almost any object to be a key, Python has specific requirements for dictionary keys.</p><h2>Keys Must Be Immutable and Hashable</h2><p>In Python, <strong>dictionary keys must be immutable and hashable</strong>. A hashable object has a hash value that doesn't change during its lifetime and can be compared to other objects. This ensures the key's hash value remains constant, allowing efficient data retrieval.</p><h3><strong>Common Immutable and Hashable Types:</strong></h3><p><strong>Integers (</strong><code>int</code><strong>):</strong></p><pre><code>my_dict = {1: "one", 2: "two"}</code></pre><p><strong>Strings (</strong><code>str</code><strong>):</strong></p><pre><code>my_dict = {"name": "Alice", "age": 30}</code></pre><p><strong>Tuples (with immutable elements):</strong></p><pre><code>my_dict = {(1, 2): "coordinates"}</code></pre><p><strong>Frozen Sets (</strong><code>frozenset</code><strong>):</strong></p><pre><code>my_dict = {frozenset({1, 2, 3}): "a frozenset"}</code></pre><p><strong>User-Defined Classes (with proper </strong><code>__hash__()</code><strong> and </strong><code>__eq__()</code><strong> methods):</strong></p><pre><code>class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __hash__(self):
        return hash((self.x, self.y))

    def __eq__(self, other):
        return (self.x, self.y) == (other.x, other.y)

my_dict = {Point(1, 2): "A point"}</code></pre><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Don&#8217;t miss these tips! Subscribe for free to receive them from me every weekday!</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>Mutable Types Cannot Be Dictionary Keys</h2><p><strong>Mutable objects are unhashable</strong> because their content can change, altering their hash value and compromising the dictionary's integrity.</p><h3><strong>Common Mutable and Unhashable Types:</strong></h3><p><strong>Lists (</strong><code>list</code><strong>):</strong></p><pre><code>my_list = [1, 2, 3]
my_dict = {my_list: "list"} # Raises TypeError</code></pre><p><strong>Dictionaries (</strong><code>dict</code><strong>):</strong></p><pre><code>my_inner_dict = {"a": 1}
my_dict = {my_inner_dict: "dict"} # Raises TypeError</code></pre><p><strong>Sets (</strong><code>set</code><strong>):</strong></p><pre><code>my_set = {1, 2, 3}
my_dict = {my_set: "set"} # Raises TypeError</code></pre><div><hr></div><h2>Understanding The Reason</h2><h3><strong>Consistency Is Crucial</strong></h3><p>When you insert a key-value pair, Python computes the hash of the key to determine where to store the value. If the key's content changes after insertion, its hash value changes, and Python can't locate the key in the dictionary anymore.</p><h3><strong>Immutability Ensures Reliability</strong></h3><p>Immutability guarantees that the key remains the same throughout its lifetime, which is essential for maintaining data integrity and efficient retrieval.</p><h2>Practical Tips for Coding Problems</h2><ul><li><p><strong>Use Immutable Types as Keys</strong></p><p>For composite keys, use tuples:</p></li></ul><pre><code>coordinates = (x, y)
my_dict[coordinates] = "value"</code></pre><ul><li><p><strong>Convert Mutable Objects to Immutable Equivalents</strong></p><p>Convert lists to tuples:</p></li></ul><pre><code>my_list = [1, 2, 3]
my_dict[tuple(my_list)] = "value"</code></pre><ul><li><p><strong>Ensure Custom Objects Are Hashable</strong></p><p>Implement <code>__hash__()</code> and <code>__eq__()</code> methods in your classes.</p></li></ul><h2>No Need to Memorize Specific Types</h2><p>Focus on the principle:<br><strong>If an object is immutable and hashable, it can be a dictionary key.</strong></p><p>You can test if an object is hashable using the <code>hash()</code> function:</p><pre><code>print(hash(42))          # Works
print(hash("hello"))     # Works
print(hash((1, 2, 3)))   # Works
print(hash([1, 2, 3]))   # Raises TypeError: unhashable type: 'list'</code></pre><div><hr></div><h2>Conclusion</h2><p>Understanding that dictionary keys must be immutable and hashable allows you to determine whether an object can serve as a key. This knowledge is essential when solving coding problems involving dictionaries or sets.</p><div><hr></div><p><strong>Stay curious and happy coding!<br>Nurbo</strong></p><p></p><h2><strong>Need Help with Coding Interviews?</strong></h2><p>If you need one-on-one help with your tech interview preparation (coding, system design or behavioral) I can probably help you. Book a free introductory session with me here: <a href="https://link.faangshui.com/book">https://link.faangshui.com/book</a>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Don&#8217;t miss these tips! Subscribe for free to receive them from me every weekday!</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Write Python Like You Mean It]]></title><description><![CDATA[How to Write Idiomatic Python and Impress Your Interviewers]]></description><link>https://blog.faangshui.com/p/write-python-like-you-mean-it</link><guid isPermaLink="false">https://blog.faangshui.com/p/write-python-like-you-mean-it</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Wed, 09 Oct 2024 18:48:05 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/46a91dee-bd86-4b34-bb8b-b378bf75c90c_1600x1067.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Python is the most popular language used in coding interviews today. Many candidates choose it even if it's not their primary language at work&#8212;and for good reason. Python is expressive, concise, and easy to learn. However, a common pitfall is that candidates code in Python but think in other languages, failing to leverage the full potential of idiomatic Python.</p><p>Below I have gathered the <strong>top mistakes</strong> non-Pythonist candidates make when writing code during interviews, along with how to improve them.</p><div><hr></div><h2>1. Inefficient Looping Over Indices Instead of Elements</h2><p><strong>How People Write It:</strong></p><pre><code>nums = [1, 2, 3, 4, 5]
for i in range(len(nums)):
    print(nums[i])</code></pre><p><strong>How It Can Be Better Written:</strong></p><pre><code>nums = [1, 2, 3, 4, 5]
for num in nums:
    print(num)</code></pre><p><strong>Explanation:</strong></p><ul><li><p><strong>Issue:</strong> Using <code>range(len(nums))</code> to iterate over list indices is unnecessary and less readable.</p></li><li><p><strong>Improvement:</strong> Directly iterate over the elements using <code>for num in nums</code>, which is more Pythonic and efficient.</p></li></ul><div><hr></div><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Don&#8217;t miss tips like this anymore. Subscribe to my daily newsletter.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><div><hr></div><h2>2. Manually Managing Loop Indices When Enumerate Exists</h2><p><strong>How People Write It:</strong></p><pre><code>words = ["apple", "banana", "cherry"]
index = 0
for word in words:
    print(f"{index}: {word}")
    index += 1</code></pre><p><strong>How It Can Be Better Written:</strong></p><pre><code>words = ["apple", "banana", "cherry"]
for index, word in enumerate(words):
    print(f"{index}: {word}")</code></pre><p><strong>Explanation:</strong></p><ul><li><p><strong>Issue:</strong> Manually incrementing an index variable is error-prone and verbose.</p></li><li><p><strong>Improvement:</strong> Use <code>enumerate()</code> to get both the index and the element in each iteration.</p></li></ul><div><hr></div><h2>3. Using Traditional Swapping Instead of Tuple Unpacking</h2><p><strong>How People Write It:</strong></p><pre><code>temp = a
a = b
b = temp</code></pre><p><strong>How It Can Be Better Written:</strong></p><pre><code>a, b = b, a</code></pre><p><strong>Explanation:</strong></p><ul><li><p><strong>Issue:</strong> The traditional method requires an extra variable and more lines of code.</p></li><li><p><strong>Improvement:</strong> Python's tuple unpacking allows swapping variables in a single, clear statement.</p></li></ul><div><hr></div><h2>4. Not Utilizing <code>defaultdict</code> for Counting</h2><p><strong>How People Write It:</strong></p><pre><code>counts = {}
for item in items:
    if item in counts:
        counts[item] += 1
    else:
        counts[item] = 1</code></pre><p><strong>How It Can Be Better Written:</strong></p><pre><code>from collections import defaultdict
counts = defaultdict(int)
for item in items:
    counts[item] += 1</code></pre><p><strong>Explanation:</strong></p><ul><li><p><strong>Issue:</strong> Manually checking for key existence leads to verbose code.</p></li><li><p><strong>Improvement:</strong> Use <code>defaultdict(int)</code> to automatically initialize counts to zero.</p></li></ul><div><hr></div><h2>5. Not Utilizing <code>Counter</code> from <code>collections</code> for Counting Elements</h2><p><strong>How People Write It:</strong></p><pre><code>def is_anagram(s, t):
    if len(s) != len(t):
        return False
    count_s = {}
    count_t = {}
    for c in s:
        count_s[c] = count_s.get(c, 0) + 1
    for c in t:
        count_t[c] = count_t.get(c, 0) + 1
    return count_s == count_t</code></pre><p><strong>How It Can Be Better Written:</strong></p><pre><code>from collections import Counter
def is_anagram(s, t):
    return Counter(s) == Counter(t)</code></pre><p><strong>Explanation:</strong></p><ul><li><p><strong>Issue:</strong> Manually counting elements is verbose and error-prone.</p></li><li><p><strong>Improvement:</strong> Use <code>Counter</code> to efficiently count elements and compare.</p></li></ul><div><hr></div><h2>6. Not Using List Comprehensions for Simple Transformations</h2><p><strong>How People Write It:</strong></p><pre><code>squares = []
for num in nums:
    squares.append(num * num)</code></pre><p><strong>How It Can Be Better Written:</strong></p><pre><code>squares = [num * num for num in nums]</code></pre><p><strong>Explanation:</strong></p><ul><li><p><strong>Issue:</strong> Using loops for simple list transformations is less concise.</p></li><li><p><strong>Improvement:</strong> List comprehensions provide a readable and efficient way to create lists.</p></li></ul><div><hr></div><h2>7. Not Using <code>zip</code> to Iterate Over Multiple Sequences</h2><p><strong>How People Write It:</strong></p><pre><code>for i in range(len(list1)):
    print(list1[i], list2[i])</code></pre><p><strong>How It Can Be Better Written:</strong></p><pre><code>for item1, item2 in zip(list1, list2):
    print(item1, item2)</code></pre><p><strong>Explanation:</strong></p><ul><li><p><strong>Issue:</strong> Using indices to access elements from multiple lists is less readable.</p></li><li><p><strong>Improvement:</strong> Use <code>zip()</code> to iterate over multiple sequences in parallel.</p></li></ul><div><hr></div><h2>8. Not Using <code>any()</code> or <code>all()</code> for Checking Conditions</h2><p><strong>How People Write It:</strong></p><pre><code>def has_positive(nums):
    for num in nums:
        if num &gt; 0:
            return True
    return False</code></pre><p><strong>How It Can Be Better Written:</strong></p><pre><code>def has_positive(nums):
    return any(num &gt; 0 for num in nums)</code></pre><p><strong>Explanation:</strong></p><ul><li><p><strong>Issue:</strong> Writing loops for simple condition checks adds unnecessary code.</p></li><li><p><strong>Improvement:</strong> Use <code>any()</code> to check if any element meets a condition.</p></li></ul><div><hr></div><h2>9. Re-Implementing <code>sum()</code>, <code>max()</code>, or <code>min()</code> Instead of Using Built-in Functions</h2><p><strong>How People Write It:</strong></p><pre><code>def find_sum(nums):
    total = 0
    for num in nums:
        total += num
    return total</code></pre><p><strong>How It Can Be Better Written:</strong></p><pre><code>def find_sum(nums):
    return sum(nums)</code></pre><p><strong>Explanation:</strong></p><ul><li><p><strong>Issue:</strong> Manually calculating sums or finding maximum/minimum values is unnecessary.</p></li><li><p><strong>Improvement:</strong> Use built-in functions like <code>sum()</code>, <code>max()</code>, and <code>min()</code> for clarity and efficiency.</p></li></ul><div><hr></div><h2>10. Not Using <code>set</code> Operations for Common Set Logic (Intersection, Union, Difference)</h2><p><strong>How People Write It:</strong></p><pre><code>def common_elements(list1, list2):
    result = []
    for item in list1:
        if item in list2:
            result.append(item)
    return result</code></pre><p><strong>How It Can Be Better Written:</strong></p><pre><code>def common_elements(list1, list2):
    return list(set(list1) &amp; set(list2))</code></pre><p><strong>Explanation:</strong></p><ul><li><p><strong>Issue:</strong> Manually checking for common elements is less efficient.</p></li><li><p><strong>Improvement:</strong> Use set operations like intersection (<code>&amp;</code>), union (<code>|</code>), and difference (<code>-</code>) for cleaner and faster code.</p></li></ul><div><hr></div><h2>11. Not Using Dictionary's <code>get()</code> Method with Default Values</h2><p><strong>How People Write It:</strong></p><pre><code>if key in my_dict:
    value = my_dict[key]
else:
    value = default_value</code></pre><p><strong>How It Can Be Better Written:</strong></p><pre><code>value = my_dict.get(key, default_value)</code></pre><p><strong>Explanation:</strong></p><ul><li><p><strong>Issue:</strong> Manually checking for key existence adds extra code.</p></li><li><p><strong>Improvement:</strong> Use <code>dict.get()</code> to simplify dictionary lookups with default values.</p></li></ul><div><hr></div><h2>12. Not Using Slicing for Reversing Strings or Lists</h2><p><strong>How People Write It:</strong></p><pre><code>def reverse_string(s):
    reversed_s = ''
    for char in s:
        reversed_s = char + reversed_s
    return reversed_s</code></pre><p><strong>How It Can Be Better Written:</strong></p><pre><code>def reverse_string(s):
    return s[::-1]</code></pre><p><strong>Explanation:</strong></p><ul><li><p><strong>Issue:</strong> Building a new string character by character is inefficient.</p></li><li><p><strong>Improvement:</strong> Use slicing with <code>[::-1]</code> to reverse strings or lists efficiently.</p></li></ul><h2>Final Thoughts</h2><p>Embracing Pythonic idioms not only makes your code more elegant but also demonstrates a deeper understanding of the language during interviews. Here's how to incorporate these practices:</p><ul><li><p><strong>Practice writing code</strong>: Solve problems using Python to internalize these idioms.</p></li><li><p><strong>Review standard library</strong>: Explore modules like <code>collections</code>, <code>itertools</code>, and built-in functions.</p></li><li><p><strong>Read others' code</strong>: Look at well-written Python code to see these idioms in action.</p></li></ul><div><hr></div><p><strong>Stay curious and happy coding!</strong></p><p><strong>Nurbo</strong></p><div><hr></div><h2><strong>Need Help with Coding Interviews?</strong></h2><p>If you need one-on-one help with your tech interview preparation (coding, system design or behavioral) I can probably help you. Book a free introductory session with me here: <a href="https://link.faangshui.com/book">https://link.faangshui.com/book</a>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Don&#8217;t miss tips like this anymore. Subscribe to my daily newsletter.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item><item><title><![CDATA[Your Resume Will Get You Only So Far]]></title><description><![CDATA[Understanding the Role of the R&#233;sum&#233; in Your Job Application]]></description><link>https://blog.faangshui.com/p/your-resume-will-get-you-only-so</link><guid isPermaLink="false">https://blog.faangshui.com/p/your-resume-will-get-you-only-so</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Tue, 08 Oct 2024 14:34:30 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/39024bbc-33a5-460e-af61-27c6f1c8b522_1456x860.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The reason you're not getting responses to your applications isn't your r&#233;sum&#233;! Stop micro-optimizing it.</p><p>Over the past two months, I've reviewed hundreds of r&#233;sum&#233;s from software engineers. <strong>Ninety percent</strong> of the folks who sent me their r&#233;sum&#233;s already had great ones and didn't need to change a single character. Yet, <strong>ninety-nine percent</strong> of them were convinced that the reason they weren't being invited to interviews was because of their r&#233;sum&#233;.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Faangshui! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><h2>What R&#233;sum&#233;s Are Really For</h2><p>Your r&#233;sum&#233; serves two primary roles in your job application:</p><ol><li><p><strong>Initial Screening by Recruiters</strong></p><p>Recruiters scan your r&#233;sum&#233; to see if your qualifications match the required criteria of the position. They then forward a select few r&#233;sum&#233;s to the hiring manager for approval to start the interview process.</p></li><li><p><strong>Verification by Hiring Managers</strong></p><p>The hiring manager looks at your r&#233;sum&#233; to verify that you have the necessary experience and skills for the position they are hiring for.</p></li></ol><p>There are other, less critical roles your r&#233;sum&#233; plays later in the process:</p><ul><li><p><strong>Interview Preparation</strong></p><p>Some interviewers might glance at your r&#233;sum&#233; before the interview. Personally, I never looked at them to limit my bias toward the interviewee.</p></li><li><p><strong>Background Checks</strong></p><p>If you receive an offer, your r&#233;sum&#233; might be used during the background check process.</p></li></ul><p>And that's essentially all your r&#233;sum&#233; is needed for.</p><h2>Why Your R&#233;sum&#233; Isn't the Problem</h2><p>The current bottleneck&#8212;the single point of failure, if you will&#8212;is <strong>Step 1: Recruiters looking at your r&#233;sum&#233;</strong>. Because there are so many applicants right now, recruiters often don't review all applications thoroughly. They just need to find a few suitable candidates. Moreover, they usually prioritize:</p><ul><li><p><strong>Referrals</strong>: Candidates recommended by current employees.</p></li><li><p><strong>Existing Applicant Database</strong>: Candidates who have applied for similar positions in the past.</p></li></ul><p>Only after exhausting these pools might they look at new applications&#8212;if at all. That's where the problem lies, and that's why you're not being invited for interviews.</p><h2>How to Solve the Issue</h2><p>You can't change the market conditions.</p><p>But you can improve your own chances.</p><p>The tech job market is tough at the moment, so while you can't fix that, you can focus on strategies to get your r&#233;sum&#233; in front of recruiters.</p><h3>So How Do You Do It?</h3><ol><li><p><strong>Leverage Referrals</strong></p><p>Referrals, referrals, referrals. There's no guarantee, but they significantly increase your chances. Reach out to your network and see if someone can refer you.</p></li><li><p><strong>Connect with Hiring Managers</strong></p><p>Even better is being referred by the hiring manager or a member of the team. This is where networking matters. Talk to people in the industry.</p></li><li><p><strong>Be Early and Consistent</strong></p><p>Apply as soon as a job is posted and be consistent with your applications. It's a numbers game, and eventually, you'll hit the pool of candidates selected for interviews.</p></li><li><p><strong>Increase Your Visibility</strong></p><ul><li><p><strong>Write a Blog</strong>: Share your knowledge and insights.</p></li><li><p><strong>Showcase Your Work</strong>: Contribute to open-source projects or build a portfolio.</p></li><li><p><strong>Engage on Professional Platforms</strong>: Be active on LinkedIn and industry forums.</p></li></ul><p>Doing interesting stuff puts you on the radar of people who hire. This is a long-term strategy, but it's the only one entirely within your control.</p></li></ol><h2>How Else to Improve the Odds</h2><ul><li><p><strong>Optimize (Don't Overhaul) Your R&#233;sum&#233;</strong></p><p>Make sure your r&#233;sum&#233; is decent: highlight the important stuff, keep it concise, and proofread it. No need to micro-optimize every detail.</p></li><li><p><strong>Tailor Your R&#233;sum&#233; to Each Job</strong></p><p>Match your r&#233;sum&#233; to the job description. If they're hiring an AI/ML engineer, make your relevant work stand out. Applying for a backend position? Emphasize your backend experience. Adjusting your r&#233;sum&#233; for each application helps recruiters see the keywords and add you to their shortlist.</p></li><li><p><strong>Be Prepared</strong></p><p>When you get that interview invite&#8212;don't blow it. Prepare thoroughly and showcase your best self.</p></li></ul><div><hr></div><p>That's all, folks. Don't blame the r&#233;sum&#233;!</p><p>Stay curious and happy coding!</p><p><strong>Nurbo</strong></p><div><hr></div><p>Psst&#8230; If you need one-on-one help with your tech interview preparation (coding, system design or behavioral) I can probably help you. Book a free session with me here: <a href="https://link.faangshui.com/book">https://link.faangshui.com/book</a>.</p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Faangshui! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div>]]></content:encoded></item><item><title><![CDATA[Why I Quit My $400K+ Job]]></title><description><![CDATA[And What I'm Doing Now]]></description><link>https://blog.faangshui.com/p/why-i-quit-my-400k-job</link><guid isPermaLink="false">https://blog.faangshui.com/p/why-i-quit-my-400k-job</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Mon, 07 Oct 2024 18:06:44 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/0d1a3294-e0bc-4367-975d-03205015201f_931x1230.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>It's been almost two months since my last day at Chime, and one of the questions I'm asked a lot is why I quit.</p><p><strong>The short answer</strong>: I wanted to take a break to figure out what to do next while reconnecting with my extended family back in my home country.</p><p>You can stop reading right there&#8212;unless you want to know the longer answer.</p><div><hr></div><h2>The Longer Answer</h2><h3>Embracing a Sabbatical</h3><p>Fifteen years ago (15 years! &#129327;), I watched a TED talk by Stefan Sagmeister called <strong>"<a href="https://www.youtube.com/watch?v=MNuOmTQdFjA">The Power of Time Off.</a>"</strong> That's when I heard the word <em>sabbatical</em> for the first time. Since then, I've always thought about how cool it would be to take one.</p><p>The basic idea of a sabbatical is to take a year off every few (usually seven) years to rest, recover, and get inspired. This is somewhat common in academia, but folks in other industries practice this as well.</p><p>Taking a sabbatical requires preparation, especially on the financial side. It eats into savings and is costly in terms of lost financial opportunities like career progression and compounding. Personally, I enjoy working, so I'm okay with retiring a bit later in life. So why not spend more time with family, work on fun stuff, and travel a bit while I'm still young and my kids are little?</p><h3>The Entrepreneurial Twist</h3><p>But here's the catch: I'm not taking the time completely off.</p><p>When I thought about what I'd do during my sabbatical, it wasn't hobbies that came to mind but a list of ideas I've been collecting for years. Most of these ideas have the potential to generate income. It's not something I specifically strive for, but creating products and businesses genuinely interests me.</p><p>I started and shut down a couple of startups many years ago, and despite the failures, that's when I had the most fun. I'd love to try starting something new again without the pressure of making it financially profitable. That's why I call this year my <strong>entrepreneurial sabbatical</strong>.</p><div><hr></div><h2>Reconnecting on the Personal Side</h2><p>I've been living in Canada for a few years now and have become a Canadian citizen. We've been fortunate to have the chance and financial means to travel to see our parents or have them visit us every year. However, every time we met, it never felt like we had enough time together. It was also hard to visit all of our extended family whenever we went home.</p><p>It felt like the right time to reconnect with our immediate and extended families. Our kids are growing up quickly, and we wanted to ensure they have a deeper connection with their grandparents, cousins, uncles, aunts, and everyone else. That's why my wife and I decided to base ourselves in our home country during this sabbatical. The lower cost of living is an added bonus.</p><div><hr></div><h2>How It's Going So Far</h2><p>My sabbatical started as we were finishing our trip to Europe, which we enjoyed immensely. After that, the last two months have been busy with non-work stuff:</p><ul><li><p><strong>Immigration Process</strong>: We had to give up our previous citizenships when we became Canadians, so we went through the immigration process again. It's strange to be an immigrant in your home country.</p></li><li><p><strong>Family Visits</strong>: We've visited our families in two cities and attended several family events.</p></li><li><p><strong>Settling In</strong>: We've been busy looking for an apartment and a daycare for our kids.</p></li></ul><h3>On the Work Front</h3><ul><li><p><strong>This Newsletter</strong>: The first thing I started is this newsletter, which has been a fulfilling way to share my journey and insights.</p></li><li><p><strong>Writing a Book</strong>: I'm working on a book about solving algorithmic (aka Leetcode) challenges, something I've been thinking about for a few years. I plan to have the beta version ready by the end of the month. Stay tuned if you want to be one of the first readers/testers!</p></li><li><p><strong>Mentoring</strong>: I've taken on a few mentees whom I'm helping prepare for their interviews on a one-on-one basis. <a href="https://calendly.com/nurbo">I have room for a few more</a>. Working closely with people is something I've enjoyed throughout my career, and I intend to continue doing it even after my sabbatical is over.</p></li></ul><div><hr></div><h2>What's Next</h2><p>Aside from releasing my book, I'm looking forward to:</p><ul><li><p><strong>Attending Weddings</strong>: Two of my high school buddies are getting married (not to each other) in the next two months. I wouldn't have been able to attend their weddings if I weren't on sabbatical.</p></li><li><p><strong>Travel Plans</strong>: I'm planning a trip to Southeast Asia in the winter and a trip to South Korea in the spring.</p></li><li><p><strong>Embracing the Unknown</strong>: Beyond that, I don't really know what I'll be doing next. And that's the beauty of this sabbatical.</p></li></ul><div><hr></div><p>Stay curious and happy coding,</p><p><strong>Nurbo</strong></p>]]></content:encoded></item><item><title><![CDATA[How Hash Tables Achieve O(1) Time Complexity]]></title><description><![CDATA[Understanding the Magic Behind Constant-Time Operations]]></description><link>https://blog.faangshui.com/p/how-hash-tables-achieve-o1-time-complexity</link><guid isPermaLink="false">https://blog.faangshui.com/p/how-hash-tables-achieve-o1-time-complexity</guid><dc:creator><![CDATA[Nurbo Kusmagul]]></dc:creator><pubDate>Fri, 04 Oct 2024 13:16:51 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/6d055b9e-5852-46d8-9b9e-fc93827a418e_566x502.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>How exactly do hash tables achieve their remarkable performance?</p><p>They perform insertion, deletion, and lookup operations in just constant average time&#8212;<strong>O(1) time complexity</strong>.</p><p>Let&#8217;s dive into the mechanics of hash tables to uncover the secrets behind their speed.</p><div><hr></div><p>At their core, hash tables (also known as hash maps or dictionaries) store key-value pairs. They provide a way to map keys to values for highly efficient data retrieval. The primary components of a hash table are:</p><ul><li><p><strong>An array (or list)</strong>: This serves as the underlying storage mechanism.</p></li><li><p><strong>A hash function</strong>: A function that takes a key and computes an index in the array where the corresponding value should be placed.</p></li></ul><h2>Achieving O(1) Time Complexity</h2><h3>1. <strong>Efficient Hash Functions</strong></h3><p>The hash function is pivotal in achieving constant-time operations. It transforms a key into an index in the array:</p><pre><code>index = hash_function(key)</code></pre><p>A good hash function has the following properties:</p><ul><li><p><strong>Deterministic</strong>: The same key always yields the same index.</p></li><li><p><strong>Uniform Distribution</strong>: It distributes keys uniformly across the array to minimize collisions.</p></li><li><p><strong>Fast Computation</strong>: It computes the index quickly to maintain O(1) performance.</p></li></ul><p>By directly computing the index, the hash function allows the hash table to jump to the exact location where the value should reside, eliminating the need for linear searches.</p><h3>2. <strong>Collision Resolution</strong></h3><p>Despite a good hash function, different keys can sometimes produce the same index&#8212;a situation known as a <strong>collision</strong>. Efficient collision resolution strategies are essential for maintaining O(1) time complexity.</p><h4><strong>Collision Resolution Techniques</strong></h4><ul><li><p><strong>Chaining (Separate Chaining)</strong>:</p><ul><li><p>Each array index points to a linked list (or another data structure) containing all key-value pairs that hash to that index.</p></li><li><p><strong>Advantage</strong>: Simple to implement and handles a large number of collisions gracefully.</p></li><li><p><strong>Average Case</strong>: O(1), assuming the linked lists remain short due to a good hash function and appropriate array size.</p></li></ul></li><li><p><strong>Open Addressing (Probing)</strong>:</p><ul><li><p>When a collision occurs, the hash table probes for the next available slot according to a probing sequence (e.g., linear probing, quadratic probing).</p></li><li><p><strong>Advantage</strong>: All data is stored within the array itself, which can improve cache performance.</p></li><li><p><strong>Average Case</strong>: O(1), but performance can degrade if the table becomes too full.</p></li></ul></li></ul><h3>3. <strong>Maintaining an Appropriate Load Factor</strong></h3><p>The <strong>load factor</strong> is the ratio of the number of stored elements to the size of the array. To maintain O(1) performance, the load factor should be kept below a certain threshold (commonly around 0.7 to 0.75).</p><ul><li><p><strong>Rehashing</strong>: When the load factor exceeds the threshold, the hash table resizes (typically doubling in size) and rehashes all existing keys into the new array. This operation is costly (O(n)) but happens infrequently and is amortized over many operations.</p></li></ul><h2>Implementation in Python</h2><p>Python's built-in <code>dict</code> type is a highly optimized hash table implementation. Let&#8217;s look at how Python achieves O(1) time complexity in its dictionaries considering the concepts discussed above.</p><h3><strong>Hash Function in Python</strong></h3><ul><li><p>Python uses the built-in <code>hash()</code> function to compute hash values for keys.</p></li><li><p>For immutable built-in types like integers, strings, and tuples, Python provides optimized hash functions.</p></li><li><p>Custom objects can define their own <code>__hash__()</code> method.</p></li></ul><p><strong>Example</strong>:</p><pre><code>key = "example"
hash_value = hash(key)</code></pre><ul><li><p>The <code>hash_value</code> is an integer that represents the hash of the key.</p></li><li><p>The hash value is then used to compute the index in the underlying array, typically via modulo operation.</p></li></ul><h3><strong>Collision Resolution in Python</strong></h3><p>Python uses <strong>Open Addressing</strong> with <strong>Perturbation Probing</strong>, a variant of <strong>Quadratic Probing</strong>.</p><h4><strong>Perturbation Probing</strong></h4><ul><li><p>When a collision occurs, Python calculates a new index using a perturbation value that changes with each probe.</p></li><li><p>This approach reduces clustering and ensures that all slots are eventually probed.</p></li></ul><p><strong>Simplified Pseudocode</strong>:</p><pre><code>index = hash(key) % array_size
perturb = hash(key)
while array[index] is not empty and array[index].key != key:
    index = (5 * index + 1 + perturb) % array_size
    perturb &gt;&gt;= 5</code></pre><ul><li><p><strong>Explanation</strong>:</p><ul><li><p><code>index</code> is the initial position calculated using the hash of the key.</p></li><li><p>If the slot at <code>index</code> is occupied by a different key, the perturbation probing sequence computes a new index.</p></li><li><p>The <code>perturb</code> variable alters the probing sequence to minimize clustering.</p></li></ul></li></ul><h3><strong>Load Factor and Resizing</strong></h3><ul><li><p>Python's dictionaries maintain a load factor of around 2/3.</p></li><li><p>When the number of entries exceeds 2/3 of the array size, the dictionary resizes to a larger size (usually doubling).</p></li><li><p>Resizing involves rehashing all existing keys into the new array.</p></li></ul><p><strong>Example</strong>:</p><pre><code># Python automatically handles resizing
my_dict = {}
for i in range(100000):
    my_dict[i] = i</code></pre><ul><li><p>In this example, <code>my_dict</code> will resize multiple times as elements are added.</p></li><li><p>The resizing ensures that the load factor remains optimal for performance.</p></li></ul><h3><strong>Optimizations in Python's Dictionaries</strong></h3><ul><li><p><strong>Entry Ordering</strong>: Since Python 3.6, dictionaries maintain insertion order.</p></li><li><p><strong>Sparse Arrays</strong>: The underlying array is kept sparse to reduce collisions.</p></li><li><p><strong>Compact Storage</strong>: Python uses a combined table to store entries efficiently, reducing memory overhead.</p></li></ul><h2>Why Hash Tables are Fast on Average</h2><p>By combining a good hash function with efficient collision resolution and maintaining a proper load factor, hash tables ensure that:</p><ul><li><p><strong>Insertions</strong>: Place the element directly at the computed index or resolve collisions quickly.</p></li><li><p><strong>Lookups</strong>: Access the element directly via its index, minimizing the number of comparisons.</p></li><li><p><strong>Deletions</strong>: Locate the element swiftly and remove it without extensive shifting of other elements.</p></li></ul><p>These factors contribute to the constant average time complexity. While the worst-case time complexity can be O(n) (e.g., when all keys collide to the same index), a well-designed hash table makes such scenarios highly unlikely.</p><div><hr></div><h2>Conclusion</h2><p>Hash tables achieve O(1) time complexity through the clever use of hash functions, efficient collision resolution techniques, and by maintaining an appropriate load factor. Python's implementation of dictionaries exemplifies these principles, providing a powerful and efficient tool for developers.</p><div><hr></div><p><strong>Key Takeaways</strong>:</p><ul><li><p><strong>Hash Functions</strong>: Transform keys into array indices for direct access.</p></li><li><p><strong>Collision Handling</strong>: Essential for maintaining performance; Python uses open addressing with perturbation probing.</p></li><li><p><strong>Load Factor</strong>: Keeping it low ensures operations remain O(1) on average.</p></li><li><p><strong>Amortized Performance</strong>: Occasional expensive operations (like rehashing) are offset by many fast operations.</p></li><li><p><strong>Immutability</strong>: Use immutable types for keys to ensure consistent hashing.</p></li></ul><div><hr></div><h3><strong>Need Help with Coding Interviews?</strong></h3><p>Are you struggling with coding problems or feeling unprepared for your upcoming interviews? You're not alone, and I'm here to help.</p><p>With years of experience as a coding interview coach, I offer personalized one-on-one sessions to:</p><ul><li><p><strong>Master problem-solving skills for coding and system design interviews</strong></p></li><li><p><strong>Boost your confidence for the big day</strong></p></li><li><p><strong>Develop effective strategies to level up your tech career</strong></p></li></ul><p><strong>Ready to elevate your coding interview skills?</strong> <strong><a href="http://link.faangshui.com/60min">Book a personalized 1:1 coaching session with me today!</a></strong></p><p>Still have questions? Let's chat! You can <a href="https://link.faangshui.com/free30min">book a </a><strong><a href="https://link.faangshui.com/free30min">free 30-minute consultation</a></strong> to discuss how I can help you achieve your goals.</p><p>Feel free to email me at <strong>nurbo.kusmagul@(google&#8217;s email service)</strong> or connect with me on <strong><a href="http://linkedin.com/in/nurbolat">LinkedIn</a></strong>.</p><p>Looking forward to helping you succeed!</p><p><em>Stay curious and happy coding!</em></p><p><em>Nurbo</em></p><div class="subscription-widget-wrap-editor" data-attrs="{&quot;url&quot;:&quot;https://blog.faangshui.com/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe&quot;,&quot;language&quot;:&quot;en&quot;}" data-component-name="SubscribeWidgetToDOM"><div class="subscription-widget show-subscribe"><div class="preamble"><p class="cta-caption">Thanks for reading Faangshui! Subscribe for free to receive new posts and support my work.</p></div><form class="subscription-widget-subscribe"><input type="email" class="email-input" name="email" placeholder="Type your email&#8230;" tabindex="-1"><input type="submit" class="button primary" value="Subscribe"><div class="fake-input-wrapper"><div class="fake-input"></div><div class="fake-button"></div></div></form></div></div><p></p>]]></content:encoded></item></channel></rss>