<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hommies</title>
    <description>The latest articles on DEV Community by Hommies (@hommies_fcbf2afe8ddb0c2a7).</description>
    <link>https://dev.to/hommies_fcbf2afe8ddb0c2a7</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3935048%2F4936ff25-ae04-441c-94d9-acce58982ad0.jpg</url>
      <title>DEV Community: Hommies</title>
      <link>https://dev.to/hommies_fcbf2afe8ddb0c2a7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hommies_fcbf2afe8ddb0c2a7"/>
    <language>en</language>
    <item>
      <title>LeetCode Solution: 5. Longest Palindromic Substring</title>
      <dc:creator>Hommies</dc:creator>
      <pubDate>Sat, 16 May 2026 18:44:09 +0000</pubDate>
      <link>https://dev.to/hommies_fcbf2afe8ddb0c2a7/leetcode-solution-5-longest-palindromic-substring-454c</link>
      <guid>https://dev.to/hommies_fcbf2afe8ddb0c2a7/leetcode-solution-5-longest-palindromic-substring-454c</guid>
      <description>&lt;h1&gt;
  
  
  Longest Palindromic Substring: A Core String Algorithm Explained
&lt;/h1&gt;

&lt;p&gt;Welcome to another deep dive into a classic LeetCode problem! Today, we're tackling Problem 5: Longest Palindromic Substring. This problem is a fantastic way to sharpen your string manipulation and algorithmic thinking skills.&lt;/p&gt;




&lt;h3&gt;
  
  
  Problem Explanation
&lt;/h3&gt;

&lt;p&gt;Given a string &lt;code&gt;s&lt;/code&gt;, our goal is to find and return the longest substring within &lt;code&gt;s&lt;/code&gt; that is a palindrome.&lt;/p&gt;

&lt;p&gt;What's a palindrome? It's a sequence of characters that reads the same forwards and backward (e.g., "madam", "racecar", "level").&lt;br&gt;
What's a substring? It's a contiguous sequence of characters within a string (e.g., for "apple", "app" is a substring, but "ale" is not).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's look at the examples:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Example 1:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Input: &lt;code&gt;s = "babad"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Output: &lt;code&gt;"bab"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Explanation: &lt;code&gt;"aba"&lt;/code&gt; is also a valid answer of the same length.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Example 2:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Input: &lt;code&gt;s = "cbbd"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Output: &lt;code&gt;"bb"&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;The string &lt;code&gt;s&lt;/code&gt; will contain only digits and English letters, and its length will be between 1 and 1000 characters.&lt;/p&gt;




&lt;h3&gt;
  
  
  Intuition
&lt;/h3&gt;

&lt;p&gt;The core idea behind finding palindromes is that they expand symmetrically from a center point. Think about "racecar" – the 'e' is the center, and 'c' expands to 'r'. Or "abba" – the center is between the two 'b's, and 'a' expands to 'a'.&lt;/p&gt;

&lt;p&gt;This insight simplifies our search: instead of checking every single substring for palindromic properties (which is &lt;code&gt;O(N^3)&lt;/code&gt; or &lt;code&gt;O(N^2)&lt;/code&gt; with an &lt;code&gt;O(N)&lt;/code&gt; check), we can iterate through every possible "center" and try to expand outwards.&lt;/p&gt;

&lt;p&gt;There are two types of centers we need to consider:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Single character center:&lt;/strong&gt; For palindromes with an odd length (e.g., "b*&lt;em&gt;a&lt;/em&gt;&lt;em&gt;b", "r&lt;/em&gt;&lt;em&gt;a&lt;/em&gt;*cecar"). Here, &lt;code&gt;s[i]&lt;/code&gt; itself is the center.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Two character center:&lt;/strong&gt; For palindromes with an even length (e.g., "bb", "a*&lt;em&gt;bb&lt;/em&gt;*a"). Here, &lt;code&gt;s[i]&lt;/code&gt; and &lt;code&gt;s[i+1]&lt;/code&gt; form the center.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Approach
&lt;/h3&gt;

&lt;p&gt;We'll use an "Expand Around Center" approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Initialize:&lt;/strong&gt; Keep track of the &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt; indices of the longest palindrome found so far. Initialize them to &lt;code&gt;0, 0&lt;/code&gt; (assuming a single character is the shortest possible palindrome).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Iterate Through Centers:&lt;/strong&gt; Loop through each character in the string using an index &lt;code&gt;i&lt;/code&gt;. Each &lt;code&gt;i&lt;/code&gt; will serve as a potential center.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Expand for Odd Length Palindromes:&lt;/strong&gt; Call a helper function &lt;code&gt;expand_around_center(s, i, i)&lt;/code&gt;. This tries to expand a palindrome assuming &lt;code&gt;s[i]&lt;/code&gt; is its sole center.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Expand for Even Length Palindromes:&lt;/strong&gt; Call the helper function &lt;code&gt;expand_around_center(s, i, i + 1)&lt;/code&gt;. This tries to expand a palindrome assuming &lt;code&gt;s[i]&lt;/code&gt; and &lt;code&gt;s[i+1]&lt;/code&gt; are its two central characters.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Helper Function &lt;code&gt;expand_around_center(s, left, right)&lt;/code&gt;:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  This function takes the string &lt;code&gt;s&lt;/code&gt; and two indices, &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  It expands outwards: &lt;code&gt;left&lt;/code&gt; moves to the left (&lt;code&gt;left-1&lt;/code&gt;) and &lt;code&gt;right&lt;/code&gt; moves to the right (&lt;code&gt;right+1&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  This expansion continues as long as &lt;code&gt;left&lt;/code&gt; is within bounds (&lt;code&gt;&amp;gt;= 0&lt;/code&gt;), &lt;code&gt;right&lt;/code&gt; is within bounds (&lt;code&gt;&amp;lt; len(s)&lt;/code&gt;), and the characters at &lt;code&gt;s[left]&lt;/code&gt; and &lt;code&gt;s[right]&lt;/code&gt; are equal.&lt;/li&gt;
&lt;li&gt;  Once the loop terminates (either due to bounds or mismatch), the length of the palindrome found is &lt;code&gt;right - left - 1&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Update Longest Palindrome:&lt;/strong&gt; After getting &lt;code&gt;len1&lt;/code&gt; (odd center) and &lt;code&gt;len2&lt;/code&gt; (even center), determine &lt;code&gt;max_len = max(len1, len2)&lt;/code&gt;. If &lt;code&gt;max_len&lt;/code&gt; is greater than the length of our current longest palindrome (&lt;code&gt;end - start + 1&lt;/code&gt;), then update &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;  To calculate the new &lt;code&gt;start&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt; from &lt;code&gt;i&lt;/code&gt; and &lt;code&gt;max_len&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;start = i - (max_len - 1) // 2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;end = i + max_len // 2&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Return Result:&lt;/strong&gt; After iterating through all possible centers, return the substring &lt;code&gt;s[start : end + 1]&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Solution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;longestPalindrome&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;

        &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

        &lt;span class="c1"&gt;# Helper function to expand around a given center
&lt;/span&gt;        &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;expand_around_center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
                &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
                &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="c1"&gt;# When the loop finishes, left and right are one step beyond the palindrome boundaries.
&lt;/span&gt;            &lt;span class="c1"&gt;# So, the length is (right - 1) - (left + 1) + 1 = right - left - 1
&lt;/span&gt;            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

        &lt;span class="c1"&gt;# Iterate through each character, treating it as a potential center
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
            &lt;span class="c1"&gt;# Case 1: Odd length palindrome (center is s[i])
&lt;/span&gt;            &lt;span class="n"&gt;len1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;expand_around_center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# Case 2: Even length palindrome (center is s[i] and s[i+1])
&lt;/span&gt;            &lt;span class="n"&gt;len2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;expand_around_center&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# Get the maximum length found from these two expansions
&lt;/span&gt;            &lt;span class="n"&gt;max_len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;len1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;len2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# If this palindrome is longer than our current longest
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;max_len&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# Calculate the new start and end indices
&lt;/span&gt;                &lt;span class="c1"&gt;# For an odd length palindrome centered at i: start = i - (length-1)/2, end = i + (length-1)/2
&lt;/span&gt;                &lt;span class="c1"&gt;# For an even length palindrome centered between i and i+1: start = i - (length/2 - 1), end = i + length/2
&lt;/span&gt;                &lt;span class="c1"&gt;# The combined formula works for both:
&lt;/span&gt;                &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_len&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
                &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;max_len&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

        &lt;span class="c1"&gt;# Return the longest palindromic substring
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Time &amp;amp; Space Complexity Analysis
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Time Complexity: O(N^2)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The main loop iterates &lt;code&gt;N&lt;/code&gt; times, where &lt;code&gt;N&lt;/code&gt; is the length of the string &lt;code&gt;s&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Inside the loop, &lt;code&gt;expand_around_center&lt;/code&gt; is called twice. In the worst case, &lt;code&gt;expand_around_center&lt;/code&gt; might traverse the entire string (e.g., for "aaaa...a").&lt;/li&gt;
&lt;li&gt;  Thus, each call to &lt;code&gt;expand_around_center&lt;/code&gt; takes &lt;code&gt;O(N)&lt;/code&gt; time.&lt;/li&gt;
&lt;li&gt;  Overall complexity: &lt;code&gt;N * O(N) = O(N^2)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Space Complexity: O(1)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We are only using a few variables (&lt;code&gt;start&lt;/code&gt;, &lt;code&gt;end&lt;/code&gt;, &lt;code&gt;i&lt;/code&gt;, &lt;code&gt;len1&lt;/code&gt;, &lt;code&gt;len2&lt;/code&gt;, &lt;code&gt;max_len&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt;, &lt;code&gt;right&lt;/code&gt;) to store indices and lengths.&lt;/li&gt;
&lt;li&gt;  The space used does not grow with the input string size.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  Key Takeaways
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Palindromes and Symmetry:&lt;/strong&gt; The inherent symmetry of palindromes is key to efficient algorithms.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Expand Around Center:&lt;/strong&gt; This is a powerful technique for palindrome problems, allowing us to find palindromes by growing them from every possible middle point.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Handling Odd and Even Lengths:&lt;/strong&gt; Remember to consider both types of palindromes (odd-length with a single character center, and even-length with a two-character center).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This "Expand Around Center" approach is generally simpler to implement than dynamic programming solutions for this problem, while achieving the same &lt;code&gt;O(N^2)&lt;/code&gt; time complexity.&lt;/p&gt;




&lt;p&gt;Author Account: p1Hzd8mRM8&lt;br&gt;
Time Published: 2026-05-17 00:13:54&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 4. Median of Two Sorted Arrays</title>
      <dc:creator>Hommies</dc:creator>
      <pubDate>Sat, 16 May 2026 18:42:44 +0000</pubDate>
      <link>https://dev.to/hommies_fcbf2afe8ddb0c2a7/leetcode-solution-4-median-of-two-sorted-arrays-1fc2</link>
      <guid>https://dev.to/hommies_fcbf2afe8ddb0c2a7/leetcode-solution-4-median-of-two-sorted-arrays-1fc2</guid>
      <description>&lt;h1&gt;
  
  
  Unlock the Median Magic: Diving into Two Sorted Arrays!
&lt;/h1&gt;

&lt;p&gt;Hey LeetCoders and aspiring developers! 👋&lt;/p&gt;

&lt;p&gt;Today, we're tackling a classic LeetCode challenge that often pops up in interviews: &lt;strong&gt;4. Median of Two Sorted Arrays&lt;/strong&gt;. Don't let the "Hard" tag intimidate you! While the optimal solution is quite advanced, we'll walk through a very intuitive, step-by-step approach that makes perfect sense for beginners. Let's conquer this one together!&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Problem Explanation: What are we actually doing?
&lt;/h2&gt;

&lt;p&gt;Imagine you have two separate lists of numbers, &lt;code&gt;nums1&lt;/code&gt; and &lt;code&gt;nums2&lt;/code&gt;, and here's the crucial part: &lt;strong&gt;both are already sorted!&lt;/strong&gt; Your mission is to find the &lt;strong&gt;median&lt;/strong&gt; of all the numbers if you were to combine these two lists into one big, sorted list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's a median?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If you have an &lt;strong&gt;odd&lt;/strong&gt; number of elements in a sorted list, the median is simply the middle element. For &lt;code&gt;[1, 2, 3]&lt;/code&gt;, the median is &lt;code&gt;2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  If you have an &lt;strong&gt;even&lt;/strong&gt; number of elements, the median is the average of the two middle elements. For &lt;code&gt;[1, 2, 3, 4]&lt;/code&gt;, the median is &lt;code&gt;(2 + 3) / 2 = 2.5&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem throws a curveball: it asks for an overall runtime complexity of &lt;code&gt;O(log(m+n))&lt;/code&gt;. We'll discuss this after exploring a more straightforward solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;nums1 = [1,3]&lt;/code&gt;, &lt;code&gt;nums2 = [2]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  If merged and sorted: &lt;code&gt;[1,2,3]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Median: &lt;code&gt;2&lt;/code&gt; (middle element)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example 2:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;nums1 = [1,2]&lt;/code&gt;, &lt;code&gt;nums2 = [3,4]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  If merged and sorted: &lt;code&gt;[1,2,3,4]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Median: &lt;code&gt;(2+3)/2 = 2.5&lt;/code&gt; (average of two middle elements)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤔 Intuition: The "Aha!" Moment
&lt;/h2&gt;

&lt;p&gt;The simplest way to find the median of two sorted arrays is to just... merge them! If we combine &lt;code&gt;nums1&lt;/code&gt; and &lt;code&gt;nums2&lt;/code&gt; into a single, sorted array, finding the median becomes trivial.&lt;/p&gt;

&lt;p&gt;However, actually building a &lt;em&gt;new&lt;/em&gt; merged array takes &lt;code&gt;O(m+n)&lt;/code&gt; space and time. Can we do it without fully merging? Yes! We only need to find the element(s) at the median position(s). We can simulate the merge process by using two pointers, one for each array, and pick elements one by one until we reach the median position.&lt;/p&gt;

&lt;p&gt;Think of it like this: you're trying to find the &lt;code&gt;k&lt;/code&gt;-th smallest element in the combined list. Since the arrays are sorted, you can always compare the current smallest elements from &lt;code&gt;nums1&lt;/code&gt; and &lt;code&gt;nums2&lt;/code&gt; to find the overall next smallest element. We'll just keep doing this until we've "counted" up to our median position.&lt;/p&gt;




&lt;h2&gt;
  
  
  🪜 Approach: Simulating the Merge (O(m+n) Time)
&lt;/h2&gt;

&lt;p&gt;Let's break down the step-by-step logic for our beginner-friendly O(m+n) approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Calculate Total Length &amp;amp; Median Positions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Find the total number of elements: &lt;code&gt;total_len = len(nums1) + len(nums2)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Determine if we need one median element (odd &lt;code&gt;total_len&lt;/code&gt;) or two (even &lt;code&gt;total_len&lt;/code&gt;). We'll need to iterate enough times to identify these elements.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialize Pointers and Median Candidates:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Use two pointers, &lt;code&gt;i&lt;/code&gt; for &lt;code&gt;nums1&lt;/code&gt; and &lt;code&gt;j&lt;/code&gt; for &lt;code&gt;nums2&lt;/code&gt;, both starting at &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Introduce two variables, &lt;code&gt;m1&lt;/code&gt; and &lt;code&gt;m2&lt;/code&gt;. &lt;code&gt;m1&lt;/code&gt; will store the &lt;em&gt;current&lt;/em&gt; element identified as we iterate through the "merged" sequence. &lt;code&gt;m2&lt;/code&gt; will store the &lt;em&gt;previous&lt;/em&gt; &lt;code&gt;m1&lt;/code&gt; value. This is crucial for when we need to average two middle elements (even &lt;code&gt;total_len&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Iterate to the Median Position(s):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We need to find elements up to &lt;code&gt;total_len // 2 + 1&lt;/code&gt;. This ensures that for an even &lt;code&gt;total_len&lt;/code&gt;, we capture both &lt;code&gt;(total_len // 2) - 1&lt;/code&gt; and &lt;code&gt;(total_len // 2)&lt;/code&gt; elements (0-indexed).&lt;/li&gt;
&lt;li&gt;  In each iteration:

&lt;ul&gt;
&lt;li&gt;  First, &lt;code&gt;m2 = m1&lt;/code&gt;. The current &lt;code&gt;m1&lt;/code&gt; becomes the "second to last" median candidate.&lt;/li&gt;
&lt;li&gt;  Then, compare the elements &lt;code&gt;nums1[i]&lt;/code&gt; and &lt;code&gt;nums2[j]&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;  If &lt;code&gt;nums1[i]&lt;/code&gt; is smaller (or &lt;code&gt;nums2&lt;/code&gt; is exhausted), pick &lt;code&gt;nums1[i]&lt;/code&gt;, assign it to &lt;code&gt;m1&lt;/code&gt;, and increment &lt;code&gt;i&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Otherwise (if &lt;code&gt;nums2[j]&lt;/code&gt; is smaller or &lt;code&gt;nums1&lt;/code&gt; is exhausted), pick &lt;code&gt;nums2[j]&lt;/code&gt;, assign it to &lt;code&gt;m1&lt;/code&gt;, and increment &lt;code&gt;j&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Calculate and Return the Median:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  After the loop finishes, &lt;code&gt;m1&lt;/code&gt; will hold the element at &lt;code&gt;total_len // 2&lt;/code&gt; (0-indexed) and &lt;code&gt;m2&lt;/code&gt; will hold the element at &lt;code&gt;(total_len // 2) - 1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  If &lt;code&gt;total_len&lt;/code&gt; is odd, &lt;code&gt;m1&lt;/code&gt; is our median.&lt;/li&gt;
&lt;li&gt;  If &lt;code&gt;total_len&lt;/code&gt; is even, the median is the average of &lt;code&gt;m1&lt;/code&gt; and &lt;code&gt;m2&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach effectively "walks" through the merged sorted array without actually building it, stopping exactly when it finds the necessary median elements.&lt;/p&gt;




&lt;h2&gt;
  
  
  💻 Code: The O(m+n) Merge-Like Solution (Python)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Solution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;findMedianSortedArrays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nums1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;nums2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;total_len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;

        &lt;span class="c1"&gt;# m1 will store the element at the current "median" position
&lt;/span&gt;        &lt;span class="c1"&gt;# m2 will store the element at the "median-1" position (for even total_len)
&lt;/span&gt;        &lt;span class="n"&gt;m1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; 

        &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="c1"&gt;# Pointers for nums1 and nums2
&lt;/span&gt;
        &lt;span class="c1"&gt;# Iterate (m + n) // 2 + 1 times to find the median element(s)
&lt;/span&gt;        &lt;span class="c1"&gt;# We need to iterate one more time than total_len // 2 for even arrays
&lt;/span&gt;        &lt;span class="c1"&gt;# to capture both m1 and m2 correctly.
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total_len&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;m2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m1&lt;/span&gt; &lt;span class="c1"&gt;# m2 takes the value m1 had in the previous iteration
&lt;/span&gt;
            &lt;span class="c1"&gt;# Logic to pick the next smallest element from either nums1 or nums2
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;nums1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;nums2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
                &lt;span class="n"&gt;m1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nums1&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; 
            &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="c1"&gt;# j &amp;lt; n and (i &amp;gt;= m or nums2[j] &amp;lt;= nums1[i])
&lt;/span&gt;                &lt;span class="n"&gt;m1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nums2&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

        &lt;span class="c1"&gt;# Check if the sum of n and m is odd.
&lt;/span&gt;        &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;ans&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ans&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⏱️ Time &amp;amp; Space Complexity Analysis
&lt;/h2&gt;

&lt;p&gt;For the O(m+n) solution we just explored:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Time Complexity: &lt;code&gt;O(m+n)&lt;/code&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  We iterate through the arrays up to &lt;code&gt;(m+n)/2 + 1&lt;/code&gt; times in the worst case. This is directly proportional to the total number of elements.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Space Complexity: &lt;code&gt;O(1)&lt;/code&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  We only use a few extra variables (&lt;code&gt;m1&lt;/code&gt;, &lt;code&gt;m2&lt;/code&gt;, &lt;code&gt;i&lt;/code&gt;, &lt;code&gt;j&lt;/code&gt;, &lt;code&gt;total_len&lt;/code&gt;). We don't create any new arrays proportional to the input size.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A Note on the &lt;code&gt;O(log(m+n))&lt;/code&gt; Requirement:&lt;/strong&gt;&lt;br&gt;
The problem statement &lt;em&gt;does&lt;/em&gt; ask for an &lt;code&gt;O(log(m+n))&lt;/code&gt; runtime complexity. This typically points to a more advanced solution involving &lt;strong&gt;binary search on partitions&lt;/strong&gt;. That approach is significantly more complex and often involves finding a "split point" in both arrays such that the elements to the left of the split form the lower half of the merged array, and elements to the right form the upper half.&lt;/p&gt;

&lt;p&gt;While our &lt;code&gt;O(m+n)&lt;/code&gt; solution is intuitive and a great starting point, mastering the &lt;code&gt;O(log(m+n))&lt;/code&gt; binary search approach is a fantastic next step once you're comfortable with this basic idea!&lt;/p&gt;




&lt;h2&gt;
  
  
  🌟 Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Simulate, Don't Always Build:&lt;/strong&gt; For problems involving sorted arrays and finding specific elements (like the median or k-th smallest), you often don't need to physically merge them. Simulating the merge with pointers is efficient.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Median Logic:&lt;/strong&gt; Remember the difference between odd and even total lengths for calculating the median. Keeping track of two "median candidate" variables (&lt;code&gt;m1&lt;/code&gt; and &lt;code&gt;m2&lt;/code&gt;) helps simplify this.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Complexity Matters:&lt;/strong&gt; Always be aware of the optimal time complexity required for a problem. While an &lt;code&gt;O(m+n)&lt;/code&gt; solution is often a good first step, understanding the &lt;code&gt;O(log(m+n))&lt;/code&gt; binary search approach for this specific problem is key for interviews.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy coding, and keep practicing! You're doing great!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Author Account: p1Hzd8mRM8&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Time Published: 2026-05-17 00:12:16&lt;/em&gt;&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 3. Longest Substring Without Repeating Characters</title>
      <dc:creator>Hommies</dc:creator>
      <pubDate>Sat, 16 May 2026 17:38:35 +0000</pubDate>
      <link>https://dev.to/hommies_fcbf2afe8ddb0c2a7/leetcode-solution-3-longest-substring-without-repeating-characters-l9l</link>
      <guid>https://dev.to/hommies_fcbf2afe8ddb0c2a7/leetcode-solution-3-longest-substring-without-repeating-characters-l9l</guid>
      <description>&lt;h1&gt;
  
  
  Sliding into Success: Solving LeetCode 3 - Longest Substring Without Repeating Characters
&lt;/h1&gt;

&lt;p&gt;Hey there, aspiring competitive programmers and curious coders!&lt;/p&gt;

&lt;p&gt;Today, we're diving into a classic LeetCode problem that's a fantastic introduction to a super useful technique: the &lt;em&gt;Sliding Window&lt;/em&gt;. It's problem #3, "Longest Substring Without Repeating Characters," and it's a rite of passage for many!&lt;/p&gt;

&lt;p&gt;Don't let the name intimidate you. By the end of this post, you'll not only understand it but also appreciate the elegance of its solution.&lt;/p&gt;




&lt;h3&gt;
  
  
  Problem Explanation: What are we actually trying to find?
&lt;/h3&gt;

&lt;p&gt;The problem asks us to find the length of the longest &lt;strong&gt;substring&lt;/strong&gt; within a given string &lt;code&gt;s&lt;/code&gt; that doesn't have any repeating characters.&lt;/p&gt;

&lt;p&gt;Let's break down some keywords:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;String &lt;code&gt;s&lt;/code&gt;&lt;/strong&gt;: This is our input, like &lt;code&gt;"abcabcbb"&lt;/code&gt; or &lt;code&gt;"pwwkew"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Substring&lt;/strong&gt;: This is a &lt;em&gt;contiguous&lt;/em&gt; sequence of characters within a string. For example, in &lt;code&gt;"abc"&lt;/code&gt;, &lt;code&gt;"a"&lt;/code&gt;, &lt;code&gt;"ab"&lt;/code&gt;, &lt;code&gt;"bc"&lt;/code&gt;, &lt;code&gt;"abc"&lt;/code&gt; are substrings. &lt;code&gt;"ac"&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; a substring because the characters aren't consecutive.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Without repeating characters&lt;/strong&gt;: Every character in our substring must be unique. If we see 'a', we can't have another 'a' in the same substring.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Let's look at the examples:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;s = "abcabcbb"&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;"abc"&lt;/code&gt; is a substring without repeating characters (length 3).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;"bca"&lt;/code&gt; is also a substring without repeating characters (length 3).&lt;/li&gt;
&lt;li&gt;  The longest such substring has a length of &lt;strong&gt;3&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;s = "bbbbb"&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;"b"&lt;/code&gt; is the longest substring without repeating characters (length 1).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;s = "pwwkew"&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;"pw"&lt;/code&gt; (length 2)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;"wke"&lt;/code&gt; (length 3) - This is our winner!&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;"kew"&lt;/code&gt; (length 3) - Another winner!&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;IMPORTANT&lt;/strong&gt;: &lt;code&gt;"pwke"&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; a substring, it's a subsequence. Remember, substrings must be contiguous. &lt;code&gt;"wke"&lt;/code&gt; is valid because 'w', 'k', 'e' are consecutive.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Our goal is to return just the &lt;em&gt;length&lt;/em&gt; of this longest unique-character substring.&lt;/p&gt;




&lt;h3&gt;
  
  
  Intuition: The "Aha!" Moment
&lt;/h3&gt;

&lt;p&gt;Imagine you're looking at a street. You want to find the longest stretch of unique houses (characters). You start walking, adding each new house you see to your mental list.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If you see a house you've already listed, you know your current unique stretch has ended &lt;em&gt;at or before&lt;/em&gt; this duplicate.&lt;/li&gt;
&lt;li&gt;  To continue, you can't just skip the duplicate. You need to "forget" houses from the &lt;em&gt;beginning&lt;/em&gt; of your current stretch until the duplicate is no longer in your list. Then, you can add the current house and keep walking.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This "walking" and "forgetting" sounds like a &lt;strong&gt;Sliding Window&lt;/strong&gt;! We'll have two pointers: &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;right&lt;/code&gt; expands our window, bringing new characters in.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;left&lt;/code&gt; shrinks our window when we encounter a duplicate, removing characters from the start until the duplicate is gone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At each step, we'll keep track of the maximum length our window has ever achieved.&lt;/p&gt;




&lt;h3&gt;
  
  
  Approach: Building Our Sliding Window
&lt;/h3&gt;

&lt;p&gt;We'll use two pointers, &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt;, to define our current "window" (substring). We also need a way to quickly check if a character is already in our current window. A &lt;code&gt;Set&lt;/code&gt; (or &lt;code&gt;HashSet&lt;/code&gt; in some languages) is perfect for this, as it allows for O(1) average time complexity for add, remove, and check operations.&lt;/p&gt;

&lt;p&gt;Here's the step-by-step logic:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialize&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;left = 0&lt;/code&gt;: This pointer marks the beginning of our current unique substring.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;max_length = 0&lt;/code&gt;: This will store the maximum length we've found so far.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;char_set = set()&lt;/code&gt;: An empty set to store characters currently within our window &lt;code&gt;[left, right]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Iterate with &lt;code&gt;right&lt;/code&gt; pointer&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We'll use a &lt;code&gt;for&lt;/code&gt; loop, letting &lt;code&gt;right&lt;/code&gt; traverse the input string &lt;code&gt;s&lt;/code&gt; from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;len(s) - 1&lt;/code&gt;. This pointer expands our window to the right.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check for Duplicates&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Inside the loop, before adding &lt;code&gt;s[right]&lt;/code&gt; to our &lt;code&gt;char_set&lt;/code&gt;, we check if &lt;code&gt;s[right]&lt;/code&gt; is &lt;em&gt;already&lt;/em&gt; in &lt;code&gt;char_set&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;If &lt;code&gt;s[right]&lt;/code&gt; IS in &lt;code&gt;char_set&lt;/code&gt; (duplicate found)&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;  This means our current window &lt;code&gt;s[left...right-1]&lt;/code&gt; has a duplicate if &lt;code&gt;s[right]&lt;/code&gt; is added.&lt;/li&gt;
&lt;li&gt;  To resolve this, we need to shrink our window from the &lt;code&gt;left&lt;/code&gt; side.&lt;/li&gt;
&lt;li&gt;  We enter a &lt;code&gt;while&lt;/code&gt; loop:

&lt;ul&gt;
&lt;li&gt;  Remove &lt;code&gt;s[left]&lt;/code&gt; from &lt;code&gt;char_set&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Increment &lt;code&gt;left&lt;/code&gt; by 1.&lt;/li&gt;
&lt;li&gt;  Repeat this until &lt;code&gt;s[right]&lt;/code&gt; is no longer in &lt;code&gt;char_set&lt;/code&gt;. This ensures our window &lt;code&gt;s[left...right-1]&lt;/code&gt; is unique &lt;em&gt;before&lt;/em&gt; we add &lt;code&gt;s[right]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;If &lt;code&gt;s[right]&lt;/code&gt; IS NOT in &lt;code&gt;char_set&lt;/code&gt; (unique character)&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;  Great! We can safely add &lt;code&gt;s[right]&lt;/code&gt; to &lt;code&gt;char_set&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Update &lt;code&gt;max_length&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  After &lt;code&gt;s[right]&lt;/code&gt; has been added (and duplicates handled if any), our current window &lt;code&gt;s[left...right]&lt;/code&gt; is guaranteed to be unique.&lt;/li&gt;
&lt;li&gt;  The length of this current unique window is &lt;code&gt;right - left + 1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Update &lt;code&gt;max_length = max(max_length, right - left + 1)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Return&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  After the &lt;code&gt;right&lt;/code&gt; pointer has traversed the entire string, &lt;code&gt;max_length&lt;/code&gt; will hold the length of the longest substring without repeating characters. Return &lt;code&gt;max_length&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's walk through &lt;code&gt;s = "abcabcbb"&lt;/code&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;right&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;s[right]&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;char_set&lt;/code&gt; (before add)&lt;/th&gt;
&lt;th&gt;Duplicate?&lt;/th&gt;
&lt;th&gt;Actions (if duplicate)&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;char_set&lt;/code&gt; (after add)&lt;/th&gt;
&lt;th&gt;&lt;code&gt;left&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;Current Length (&lt;code&gt;right - left + 1&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;&lt;code&gt;max_length&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;'a'&lt;/td&gt;
&lt;td&gt;{}&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;{'a'}&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;'b'&lt;/td&gt;
&lt;td&gt;{'a'}&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;{'a', 'b'}&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;'c'&lt;/td&gt;
&lt;td&gt;{'a', 'b'}&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;{'a', 'b', 'c'}&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;'a'&lt;/td&gt;
&lt;td&gt;{'a', 'b', 'c'}&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;char_set.remove('a')&lt;/code&gt;, &lt;code&gt;left=1&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;{'b', 'c', 'a'}&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;3 (&lt;code&gt;3 - 1 + 1&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;'b'&lt;/td&gt;
&lt;td&gt;{'b', 'c', 'a'}&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;char_set.remove('b')&lt;/code&gt;, &lt;code&gt;left=2&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;{'c', 'a', 'b'}&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;3 (&lt;code&gt;4 - 2 + 1&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;'c'&lt;/td&gt;
&lt;td&gt;{'c', 'a', 'b'}&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;char_set.remove('c')&lt;/code&gt;, &lt;code&gt;left=3&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;{'a', 'b', 'c'}&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3 (&lt;code&gt;5 - 3 + 1&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;'b'&lt;/td&gt;
&lt;td&gt;{'a', 'b', 'c'}&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;char_set.remove('a')&lt;/code&gt;, &lt;code&gt;left=4&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;{'b', 'c', 'b'}&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;3 (&lt;code&gt;6 - 4 + 1&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;char_set.remove('b')&lt;/code&gt;, &lt;code&gt;left=5&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;{'c', 'b'}&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;2 (&lt;code&gt;6 - 5 + 1&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Final &lt;code&gt;max_length&lt;/code&gt; is 3. This trace confirms the logic!&lt;/p&gt;




&lt;h3&gt;
  
  
  Code: Bringing it to life with Python
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Solution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lengthOfLongestSubstring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# A set to keep track of characters in the current window
&lt;/span&gt;        &lt;span class="n"&gt;char_set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="c1"&gt;# Left pointer of the sliding window
&lt;/span&gt;        &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

        &lt;span class="c1"&gt;# Variable to store the maximum length found so far
&lt;/span&gt;        &lt;span class="n"&gt;max_length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

        &lt;span class="c1"&gt;# Right pointer iterates through the string
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
            &lt;span class="c1"&gt;# If the character at 'right' is already in our set,
&lt;/span&gt;            &lt;span class="c1"&gt;# it means we have a duplicate within the current window.
&lt;/span&gt;            &lt;span class="c1"&gt;# We need to shrink the window from the 'left' until the duplicate is removed.
&lt;/span&gt;            &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;char_set&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;char_set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# Remove the character at 'left' from the set
&lt;/span&gt;                &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;                &lt;span class="c1"&gt;# Move the 'left' pointer one step to the right
&lt;/span&gt;
            &lt;span class="c1"&gt;# Now that the current character s[right] is guaranteed to be unique
&lt;/span&gt;            &lt;span class="c1"&gt;# in the window [left...right-1], we can add it to our set.
&lt;/span&gt;            &lt;span class="n"&gt;char_set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

            &lt;span class="c1"&gt;# Update the maximum length found.
&lt;/span&gt;            &lt;span class="c1"&gt;# The current window length is (right - left + 1).
&lt;/span&gt;            &lt;span class="n"&gt;max_length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;max_length&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Time &amp;amp; Space Complexity Analysis
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Time Complexity: O(N)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Both the &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; pointers traverse the string &lt;code&gt;s&lt;/code&gt; at most once.&lt;/li&gt;
&lt;li&gt;  The &lt;code&gt;right&lt;/code&gt; pointer moves &lt;code&gt;N&lt;/code&gt; times.&lt;/li&gt;
&lt;li&gt;  The &lt;code&gt;left&lt;/code&gt; pointer also moves at most &lt;code&gt;N&lt;/code&gt; times across all iterations of the outer loop.&lt;/li&gt;
&lt;li&gt;  Set operations (add, remove, check &lt;code&gt;in&lt;/code&gt;) take O(1) average time.&lt;/li&gt;
&lt;li&gt;  Therefore, the total time complexity is linear, O(N), where &lt;code&gt;N&lt;/code&gt; is the length of the string &lt;code&gt;s&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Space Complexity: O(min(M, N))&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We use a &lt;code&gt;char_set&lt;/code&gt; to store unique characters within the window.&lt;/li&gt;
&lt;li&gt;  In the worst case, if all characters in the string are unique (e.g., "abcdefg"), the set will store &lt;code&gt;N&lt;/code&gt; characters.&lt;/li&gt;
&lt;li&gt;  However, if the character set is limited (e.g., lowercase English letters, &lt;code&gt;M=26&lt;/code&gt;), the set will store at most &lt;code&gt;M&lt;/code&gt; characters.&lt;/li&gt;
&lt;li&gt;  So, the space complexity is bounded by the smaller of the string's length &lt;code&gt;N&lt;/code&gt; and the size of the character set &lt;code&gt;M&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  Key Takeaways
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Sliding Window Technique&lt;/strong&gt;: This problem is a prime example of the "sliding window" pattern, which is incredibly useful for array/string problems involving a contiguous subsegment. It helps optimize solutions from O(N^2) (e.g., checking every possible substring) to O(N).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;&lt;code&gt;Set&lt;/code&gt; for Uniqueness Checks&lt;/strong&gt;: Using a hash set (&lt;code&gt;set&lt;/code&gt; in Python) is crucial for efficient O(1) average-time lookups, insertions, and deletions, which allows the sliding window to perform optimally.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Two Pointers (Left and Right)&lt;/strong&gt;: The &lt;code&gt;left&lt;/code&gt; pointer helps shrink the window when a condition is violated (duplicate found), while the &lt;code&gt;right&lt;/code&gt; pointer expands it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Keep practicing, and you'll master these patterns in no time! Happy coding!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Author Account: p1Hzd8mRM8&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Time Published: 2026-05-16 23:08:20&lt;/em&gt;&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 3. Longest Substring Without Repeating Characters</title>
      <dc:creator>Hommies</dc:creator>
      <pubDate>Sat, 16 May 2026 17:30:51 +0000</pubDate>
      <link>https://dev.to/hommies_fcbf2afe8ddb0c2a7/leetcode-solution-3-longest-substring-without-repeating-characters-2nm3</link>
      <guid>https://dev.to/hommies_fcbf2afe8ddb0c2a7/leetcode-solution-3-longest-substring-without-repeating-characters-2nm3</guid>
      <description>&lt;h1&gt;
  
  
  Cracking LeetCode 3: The Longest Substring Without Repeating Characters (A Sliding Window Adventure!)
&lt;/h1&gt;

&lt;p&gt;Hey Devs! 👋 Ever stumbled upon a LeetCode problem that looks simple but hides a powerful algorithmic pattern? Today, we're diving into LeetCode problem #3, "Longest Substring Without Repeating Characters." This classic problem is a fantastic introduction to a super common and efficient technique: the &lt;strong&gt;Sliding Window&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Don't worry if that sounds intimidating – we'll break it down piece by piece, like LEGOs! By the end of this post, you'll not only understand the solution but also gain a valuable tool for tackling similar string and array problems. Let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Unpacking "Longest Substring Without Repeating Characters"
&lt;/h2&gt;

&lt;p&gt;Imagine you're given a string, like "abcabcbb". Your mission, should you choose to accept it, is to find the longest &lt;em&gt;substring&lt;/em&gt; within it that doesn't have any character repeated.&lt;/p&gt;

&lt;p&gt;Let's clarify some terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Substring&lt;/strong&gt;: A contiguous sequence of characters within a string. "abc" is a substring of "abcabcbb", but "acb" is not.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Without Repeating Characters&lt;/strong&gt;: Every character in our chosen substring must be unique. No 'a' appearing twice, no 'b' appearing twice, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Examples to make it crystal clear:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Input: &lt;code&gt;s = "abcabcbb"&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  "abc" is a substring without repeating characters (length 3).&lt;/li&gt;
&lt;li&gt;  "bca" is also valid (length 3).&lt;/li&gt;
&lt;li&gt;  "abcab" is NOT valid because 'a' and 'b' repeat.&lt;/li&gt;
&lt;li&gt;  The longest one we can find is "abc" (or "bca", "cab"), with a length of &lt;strong&gt;3&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Input: &lt;code&gt;s = "bbbbb"&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The longest substring without repeating characters is just "b" (length &lt;strong&gt;1&lt;/strong&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Input: &lt;code&gt;s = "pwwkew"&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  "pwke" is NOT a substring; it's a &lt;em&gt;subsequence&lt;/em&gt; (characters appear in order but not necessarily contiguously).&lt;/li&gt;
&lt;li&gt;  "wke" IS a substring without repeating characters (length 3).&lt;/li&gt;
&lt;li&gt;  "pww" has repeating 'w'.&lt;/li&gt;
&lt;li&gt;  The longest is "wke" (length &lt;strong&gt;3&lt;/strong&gt;).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;The goal is to return just the &lt;em&gt;length&lt;/em&gt; of this longest unique substring.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Intuition: Why a "Sliding Window"?
&lt;/h2&gt;

&lt;p&gt;If you're new to competitive programming, your first thought might be: "Let's check every possible substring!" And that's a valid starting point. You could have two loops, &lt;code&gt;i&lt;/code&gt; and &lt;code&gt;j&lt;/code&gt;, generating all substrings &lt;code&gt;s[i:j+1]&lt;/code&gt;, and for each, check if it has repeating characters. This would work, but it's pretty slow (think O(N^3) or O(N^2) depending on how you check uniqueness). Can we do better? Absolutely!&lt;/p&gt;

&lt;p&gt;The "aha!" moment comes when you realize that if you have a substring &lt;code&gt;s[left...right]&lt;/code&gt; that contains duplicate characters, you don't need to re-examine the &lt;em&gt;entire&lt;/em&gt; string from scratch. You just need to &lt;em&gt;adjust&lt;/em&gt; your current substring until it becomes valid again.&lt;/p&gt;

&lt;p&gt;This is where the &lt;strong&gt;Sliding Window&lt;/strong&gt; technique shines! Imagine a window "sliding" over the string. This window represents our current substring.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We try to expand the window from the &lt;code&gt;right&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  If we add a character that causes a duplicate, we shrink the window from the &lt;code&gt;left&lt;/code&gt; until the duplicate is gone.&lt;/li&gt;
&lt;li&gt;  At each valid step, we keep track of the maximum length our window has achieved.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Approach: Two Pointers and a Set
&lt;/h2&gt;

&lt;p&gt;Let's formalize our sliding window approach using two pointers, &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt;, and a &lt;code&gt;set&lt;/code&gt; to efficiently track characters within our current window.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialize:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;max_length = 0&lt;/code&gt;: This will store our answer.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;left = 0&lt;/code&gt;: This pointer marks the beginning of our current unique substring window.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;char_set = set()&lt;/code&gt;: This set will hold all characters currently inside our &lt;code&gt;s[left...right]&lt;/code&gt; window. Sets are perfect because they only store unique items and offer super fast &lt;code&gt;add&lt;/code&gt;, &lt;code&gt;remove&lt;/code&gt;, and &lt;code&gt;in&lt;/code&gt; (contains) operations (average O(1) time complexity).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Iterate with the &lt;code&gt;right&lt;/code&gt; pointer:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We'll use a &lt;code&gt;for&lt;/code&gt; loop with &lt;code&gt;right&lt;/code&gt; iterating from &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;len(s) - 1&lt;/code&gt;. This pointer expands our window to the right.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check for Duplicates and Shrink the Window:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Inside the loop, before adding &lt;code&gt;s[right]&lt;/code&gt; to our &lt;code&gt;char_set&lt;/code&gt;, we need to check if &lt;code&gt;s[right]&lt;/code&gt; is &lt;em&gt;already&lt;/em&gt; in &lt;code&gt;char_set&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;If &lt;code&gt;s[right]&lt;/code&gt; is ALREADY in &lt;code&gt;char_set&lt;/code&gt;&lt;/strong&gt;: This means we have a duplicate! Our current window &lt;code&gt;s[left...right-1]&lt;/code&gt; was unique, but &lt;code&gt;s[right]&lt;/code&gt; broke the rule.

&lt;ul&gt;
&lt;li&gt;  To fix this, we need to shrink the window from the &lt;code&gt;left&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  We repeatedly &lt;code&gt;remove&lt;/code&gt; &lt;code&gt;s[left]&lt;/code&gt; from &lt;code&gt;char_set&lt;/code&gt; and increment &lt;code&gt;left&lt;/code&gt; until &lt;code&gt;s[right]&lt;/code&gt; is no longer a duplicate within our window.&lt;/li&gt;
&lt;li&gt;  Think of it as kicking out characters from the left until the culprit (the first instance of the duplicate) is gone.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Expand the Window and Update Max Length:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Once &lt;code&gt;s[right]&lt;/code&gt; is guaranteed to be unique within our current (possibly shrunken) window, &lt;code&gt;add&lt;/code&gt; &lt;code&gt;s[right]&lt;/code&gt; to &lt;code&gt;char_set&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Now, our current window &lt;code&gt;s[left...right]&lt;/code&gt; is valid (all unique characters). Calculate its length: &lt;code&gt;right - left + 1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Update &lt;code&gt;max_length = max(max_length, right - left + 1)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Return &lt;code&gt;max_length&lt;/code&gt;:&lt;/strong&gt; After the &lt;code&gt;right&lt;/code&gt; pointer has traversed the entire string, &lt;code&gt;max_length&lt;/code&gt; will hold the length of the longest substring without repeating characters.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's trace &lt;code&gt;s = "abcabcbb"&lt;/code&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;code&gt;right&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;s[right]&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;char_set&lt;/code&gt; (before &lt;code&gt;s[right]&lt;/code&gt; check)&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;s[right]&lt;/code&gt; in &lt;code&gt;char_set&lt;/code&gt;?&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;char_set&lt;/code&gt; (after fix)&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;left&lt;/code&gt; (after fix)&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;char_set&lt;/code&gt; (after add &lt;code&gt;s[right]&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;Current Window (&lt;code&gt;s[left...right]&lt;/code&gt;)&lt;/th&gt;
&lt;th&gt;Current Length&lt;/th&gt;
&lt;th&gt;&lt;code&gt;max_length&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{a}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{a}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{a}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{a, b}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ab&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{a, b}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{a, b}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{a, b, c}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;abc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{a, b, c}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;True&lt;/code&gt; (a repeats)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{b, c}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{b, c, a}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;bca&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{b, c, a}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;True&lt;/code&gt; (b repeats)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{c, a}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{c, a, b}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cab&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{c, a, b}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;True&lt;/code&gt; (c repeats)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{a, b}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{a, b, c}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;abc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;6&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{a, b, c}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;True&lt;/code&gt; (b repeats)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{c}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{c, b}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cb&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;7&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{c, b}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;True&lt;/code&gt; (b repeats)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;7&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{b}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Finally, &lt;code&gt;max_length&lt;/code&gt; is &lt;code&gt;3&lt;/code&gt;! This matches the example.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Solution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lengthOfLongestSubstring&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;char_set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# To store characters in the current window
&lt;/span&gt;        &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;         &lt;span class="c1"&gt;# Left pointer of the sliding window
&lt;/span&gt;        &lt;span class="n"&gt;max_length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;   &lt;span class="c1"&gt;# Stores the maximum length found so far
&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
            &lt;span class="c1"&gt;# While the character at 'right' is already in our set (duplicate detected)
&lt;/span&gt;            &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;char_set&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# Remove the character at 'left' from the set
&lt;/span&gt;                &lt;span class="n"&gt;char_set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
                &lt;span class="c1"&gt;# Move the 'left' pointer to shrink the window
&lt;/span&gt;                &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

            &lt;span class="c1"&gt;# Add the current character at 'right' to the set
&lt;/span&gt;            &lt;span class="c1"&gt;# Now, the window s[left...right] is guaranteed to have unique characters
&lt;/span&gt;            &lt;span class="n"&gt;char_set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

            &lt;span class="c1"&gt;# Update the maximum length found
&lt;/span&gt;            &lt;span class="n"&gt;max_length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;max_length&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Time &amp;amp; Space Complexity Analysis
&lt;/h2&gt;

&lt;p&gt;This is where the sliding window truly shines!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Time Complexity: O(N)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The &lt;code&gt;right&lt;/code&gt; pointer iterates through the string &lt;code&gt;s&lt;/code&gt; exactly once, performing &lt;code&gt;N&lt;/code&gt; steps.&lt;/li&gt;
&lt;li&gt;  The &lt;code&gt;left&lt;/code&gt; pointer also iterates through the string at most once (it only moves forward).&lt;/li&gt;
&lt;li&gt;  Each character is added to the &lt;code&gt;char_set&lt;/code&gt; once and removed from the &lt;code&gt;char_set&lt;/code&gt; at most once.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;set&lt;/code&gt; operations (add, remove, check &lt;code&gt;in&lt;/code&gt;) take average O(1) time.&lt;/li&gt;
&lt;li&gt;  Therefore, the total time complexity is linear, O(N), where N is the length of the string &lt;code&gt;s&lt;/code&gt;. This is super efficient!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Space Complexity: O(min(N, M))&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;char_set&lt;/code&gt; stores characters from the current window.&lt;/li&gt;
&lt;li&gt;  In the worst case, if all characters are unique, the set could store up to &lt;code&gt;N&lt;/code&gt; characters (where N is &lt;code&gt;len(s)&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  However, the maximum size of the &lt;code&gt;char_set&lt;/code&gt; is also limited by the size of the character set (e.g., 26 for lowercase English letters, 128 for ASCII, 256 for extended ASCII). Let &lt;code&gt;M&lt;/code&gt; be the size of the alphabet.&lt;/li&gt;
&lt;li&gt;  So, the space complexity is O(min(N, M)). For typical interview problems dealing with ASCII characters, this is often considered O(1) constant space because &lt;code&gt;M&lt;/code&gt; (e.g., 128 or 256) is a fixed constant regardless of the input string's length.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Sliding Window Power&lt;/strong&gt;: This problem is a perfect introduction to the sliding window pattern. Remember it for problems involving finding optimal subarrays or substrings.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Two Pointers&lt;/strong&gt;: The &lt;code&gt;left&lt;/code&gt; and &lt;code&gt;right&lt;/code&gt; pointers are crucial for defining and moving the window efficiently.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Hash Set (Set) for Uniqueness&lt;/strong&gt;: A &lt;code&gt;set&lt;/code&gt; is your best friend when you need to quickly check for the presence of an element and ensure uniqueness. Its O(1) average time complexity for lookups, insertions, and deletions is key to the overall efficiency.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Distinguish Substring vs. Subsequence&lt;/strong&gt;: Always pay attention to whether the problem asks for a &lt;em&gt;substring&lt;/em&gt; (contiguous) or a &lt;em&gt;subsequence&lt;/em&gt; (order preserved, not necessarily contiguous).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Congratulations! You've successfully navigated one of LeetCode's most popular problems and added the powerful Sliding Window technique to your algorithmic toolkit. Keep practicing, and these patterns will become second nature!&lt;/p&gt;




&lt;p&gt;Published by p1Hzd8mRM8 on 2026-05-16 23:00:35&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 2. Add Two Numbers</title>
      <dc:creator>Hommies</dc:creator>
      <pubDate>Sat, 16 May 2026 17:28:37 +0000</pubDate>
      <link>https://dev.to/hommies_fcbf2afe8ddb0c2a7/leetcode-solution-2-add-two-numbers-5074</link>
      <guid>https://dev.to/hommies_fcbf2afe8ddb0c2a7/leetcode-solution-2-add-two-numbers-5074</guid>
      <description>&lt;h1&gt;
  
  
  🚀 Cracking LeetCode #2: Adding Two Numbers Like a Pro (with Linked Lists!) 🚀
&lt;/h1&gt;

&lt;p&gt;Hey there, future coding rockstars! 👋 Today, we're diving into a LeetCode classic that often stumps beginners but is incredibly satisfying once you "get" it. We're talking about &lt;strong&gt;LeetCode Problem #2: Add Two Numbers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This problem is a fantastic introduction to manipulating linked lists and thinking about how computers handle fundamental operations like arithmetic. Ready to conquer it? Let's go!&lt;/p&gt;




&lt;h3&gt;
  
  
  The Problem Explained: Adding Numbers, But Backwards! 🤯
&lt;/h3&gt;

&lt;p&gt;Imagine you want to add two big numbers, like 342 and 465. Normally, you'd write them down and add them from right to left (units, tens, hundreds, etc.), carrying over any extra digits.&lt;/p&gt;

&lt;p&gt;Now, imagine these numbers aren't stored as regular integers but as &lt;strong&gt;linked lists&lt;/strong&gt;. If you're new to linked lists, think of them as a chain of boxes (nodes), where each box holds a value and points to the &lt;em&gt;next&lt;/em&gt; box in the chain.&lt;/p&gt;

&lt;p&gt;The twist? The digits are stored in &lt;strong&gt;reverse order&lt;/strong&gt;!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;l1 = [2,4,3]&lt;/code&gt; actually represents the number &lt;strong&gt;342&lt;/strong&gt;. (3 -&amp;gt; 4 -&amp;gt; 2, but read from the head: 2 is units, 4 is tens, 3 is hundreds).&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;l2 = [5,6,4]&lt;/code&gt; actually represents the number &lt;strong&gt;465&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our goal is to &lt;strong&gt;add these two numbers&lt;/strong&gt; (342 + 465) and return their &lt;strong&gt;sum&lt;/strong&gt; (807) also as a linked list in reverse order: &lt;code&gt;[7,0,8]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's look at the examples:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1:&lt;/strong&gt;&lt;br&gt;
Input: &lt;code&gt;l1 = [2,4,3]&lt;/code&gt; (342), &lt;code&gt;l2 = [5,6,4]&lt;/code&gt; (465)&lt;br&gt;
Output: &lt;code&gt;[7,0,8]&lt;/code&gt; (807)&lt;br&gt;
Explanation: 2 + 5 = 7. 4 + 6 = 10 (0 with carry 1). 3 + 4 + 1 (carry) = 8. So, [7, 0, 8].&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 2:&lt;/strong&gt;&lt;br&gt;
Input: &lt;code&gt;l1 = [0]&lt;/code&gt;, &lt;code&gt;l2 = [0]&lt;/code&gt;&lt;br&gt;
Output: &lt;code&gt;[0]&lt;/code&gt;&lt;br&gt;
Explanation: 0 + 0 = 0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 3:&lt;/strong&gt;&lt;br&gt;
Input: &lt;code&gt;l1 = [9,9,9,9,9,9,9]&lt;/code&gt;, &lt;code&gt;l2 = [9,9,9,9]&lt;/code&gt;&lt;br&gt;
Output: &lt;code&gt;[8,9,9,9,0,0,0,1]&lt;/code&gt;&lt;br&gt;
Explanation: This one shows longer lists and the need to handle a final carry! 9,999,999 + 9,999 = 10,009,998.&lt;/p&gt;


&lt;h3&gt;
  
  
  The "Aha!" Moment: Mimicking Manual Addition 💡
&lt;/h3&gt;

&lt;p&gt;The key to solving this problem lies in realizing that since the digits are already in &lt;em&gt;reverse order&lt;/em&gt;, the head of each linked list contains the &lt;strong&gt;least significant digit&lt;/strong&gt; (the "ones" place). This is exactly where we start when we add numbers by hand!&lt;/p&gt;

&lt;p&gt;So, the "aha!" moment is: &lt;strong&gt;we can simply iterate through both linked lists simultaneously, adding digits just like we would with pen and paper.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For each "place value":&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Add the corresponding digits from &lt;code&gt;l1&lt;/code&gt; and &lt;code&gt;l2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Don't forget to add any &lt;code&gt;carry&lt;/code&gt; from the previous addition!&lt;/li&gt;
&lt;li&gt; The sum of these three numbers (digit1 + digit2 + carry) will give us a &lt;code&gt;total_sum&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; The new digit for our result list will be &lt;code&gt;total_sum % 10&lt;/code&gt; (the remainder when divided by 10).&lt;/li&gt;
&lt;li&gt; The new &lt;code&gt;carry&lt;/code&gt; for the next iteration will be &lt;code&gt;total_sum // 10&lt;/code&gt; (the quotient when divided by 10).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We continue this process until we've gone through both lists &lt;em&gt;and&lt;/em&gt; handled any final carry.&lt;/p&gt;


&lt;h3&gt;
  
  
  The Step-by-Step Approach 🚶‍♂️
&lt;/h3&gt;

&lt;p&gt;Let's break down the logic into concrete steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Initialize a Dummy Head:&lt;/strong&gt; Create a &lt;code&gt;dummy&lt;/code&gt; node. This is a common trick with linked lists! It acts as a placeholder for the beginning of our result list. We'll eventually return &lt;code&gt;dummy.next&lt;/code&gt; to skip this placeholder.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Current Pointer for Result:&lt;/strong&gt; Create a &lt;code&gt;res&lt;/code&gt; pointer and point it to &lt;code&gt;dummy&lt;/code&gt;. This &lt;code&gt;res&lt;/code&gt; pointer will move along as we build our new linked list.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Initialize Carry:&lt;/strong&gt; Set a &lt;code&gt;carry&lt;/code&gt; variable to &lt;code&gt;0&lt;/code&gt;. This will store any carry-over digit from our additions.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Loop Until Done:&lt;/strong&gt; We need to keep adding as long as there are digits in &lt;code&gt;l1&lt;/code&gt;, digits in &lt;code&gt;l2&lt;/code&gt;, or a &lt;code&gt;carry&lt;/code&gt; remaining. So, our loop condition will be &lt;code&gt;while l1 or l2 or carry:&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Get Current Digits:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  If &lt;code&gt;l1&lt;/code&gt; exists, get its &lt;code&gt;val&lt;/code&gt;. Otherwise, consider it &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  If &lt;code&gt;l2&lt;/code&gt; exists, get its &lt;code&gt;val&lt;/code&gt;. Otherwise, consider it &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  This handles lists of unequal lengths gracefully.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Calculate Sum:&lt;/strong&gt; &lt;code&gt;total_sum = val1 + val2 + carry&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;New Digit and New Carry:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  The &lt;code&gt;digit&lt;/code&gt; for our new node is &lt;code&gt;total_sum % 10&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  The &lt;code&gt;carry&lt;/code&gt; for the next iteration is &lt;code&gt;total_sum // 10&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Create and Append New Node:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  Create a new &lt;code&gt;ListNode&lt;/code&gt; with the calculated &lt;code&gt;digit&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Append this new node to our result list: &lt;code&gt;res.next = new_node&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Move our &lt;code&gt;res&lt;/code&gt; pointer forward: &lt;code&gt;res = res.next&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Advance Input Pointers:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  If &lt;code&gt;l1&lt;/code&gt; is not &lt;code&gt;None&lt;/code&gt;, move &lt;code&gt;l1 = l1.next&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  If &lt;code&gt;l2&lt;/code&gt; is not &lt;code&gt;None&lt;/code&gt;, move &lt;code&gt;l2 = l2.next&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Return Result:&lt;/strong&gt; Once the loop finishes, return &lt;code&gt;dummy.next&lt;/code&gt;. This skips our initial placeholder node and gives us the actual head of our sum list.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach perfectly mimics how we'd add numbers by hand, ensuring we handle carries and lists of different lengths.&lt;/p&gt;


&lt;h3&gt;
  
  
  The Code 🧑‍💻
&lt;/h3&gt;

&lt;p&gt;Here's the Python implementation based on our approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Definition for singly-linked list.
# This part is usually provided by LeetCode or you define it yourself.
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Solution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;addTwoNumbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;l1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;

        &lt;span class="c1"&gt;# 1. Initialize a dummy head for the result list
&lt;/span&gt;        &lt;span class="n"&gt;dummy_head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="c1"&gt;# 2. 'current' pointer to build the result list
&lt;/span&gt;        &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dummy_head&lt;/span&gt; 

        &lt;span class="c1"&gt;# 3. Initialize carry to 0
&lt;/span&gt;        &lt;span class="n"&gt;carry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

        &lt;span class="c1"&gt;# 4. Loop as long as there are digits in either list OR a carry remains
&lt;/span&gt;        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;l1&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;carry&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# 5. Get current digits (or 0 if list is exhausted)
&lt;/span&gt;            &lt;span class="n"&gt;val1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;l1&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
            &lt;span class="n"&gt;val2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

            &lt;span class="c1"&gt;# 6. Calculate the total sum for the current position
&lt;/span&gt;            &lt;span class="n"&gt;total_sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;val1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;val2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;carry&lt;/span&gt;

            &lt;span class="c1"&gt;# 7. Determine the digit for the current node and the new carry
&lt;/span&gt;            &lt;span class="n"&gt;new_digit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total_sum&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
            &lt;span class="n"&gt;carry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total_sum&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

            &lt;span class="c1"&gt;# 8. Create a new node and append it to our result list
&lt;/span&gt;            &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_digit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="c1"&gt;# Move the 'current' pointer forward
&lt;/span&gt;            &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;

            &lt;span class="c1"&gt;# 9. Advance input list pointers if they exist
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;l1&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;l1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;l2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;

        &lt;span class="c1"&gt;# 10. Return the actual head of the sum list (skipping the dummy_head)
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;dummy_head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Time &amp;amp; Space Complexity Analysis ⏱️📏
&lt;/h3&gt;

&lt;p&gt;Understanding how much time and memory your solution uses is crucial for competitive programming!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Time Complexity: O(max(N, M))&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Where &lt;code&gt;N&lt;/code&gt; is the number of nodes in &lt;code&gt;l1&lt;/code&gt; and &lt;code&gt;M&lt;/code&gt; is the number of nodes in &lt;code&gt;l2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  We iterate through both linked lists at most once. The loop continues for a number of iterations equal to the length of the longer list, plus potentially one more if there's a final carry. Hence, the time taken scales linearly with the length of the longer input list.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Space Complexity: O(max(N, M))&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We create a new linked list to store the sum. In the worst case (e.g., adding two numbers like &lt;code&gt;[9,9,9]&lt;/code&gt; and &lt;code&gt;[1]&lt;/code&gt;), the result list can be one node longer than the longer input list (&lt;code&gt;[0,0,0,1]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  Therefore, the space used to store the result scales linearly with the length of the longer input list.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  Key Takeaways ✨
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Simulate Manual Processes:&lt;/strong&gt; Many problems, especially arithmetic ones, can be solved by translating your "pen-and-paper" method into code.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;The Power of a Dummy Node:&lt;/strong&gt; A dummy head node is a fantastic pattern for simplifying linked list operations, especially when you're building a new list or might need to modify the original head. It avoids annoying edge cases where you'd have to handle the first node creation separately.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Handling Carries and Unequal Lengths:&lt;/strong&gt; This problem is a great example of how to manage state (the &lt;code&gt;carry&lt;/code&gt;) between iterations and gracefully handle inputs of different sizes.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Linked Lists for Big Numbers:&lt;/strong&gt; Linked lists are often used in computer science to represent numbers of arbitrary length, exceeding what standard integer types can hold.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Congratulations! You've just walked through a fundamental LeetCode problem, learned about linked lists, and developed a solid approach. Keep practicing, and you'll be crushing those interviews in no time!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Authored by p1Hzd8mRM8. Published on 2026-05-16 22:58:14.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 2. Add Two Numbers</title>
      <dc:creator>Hommies</dc:creator>
      <pubDate>Sat, 16 May 2026 16:58:02 +0000</pubDate>
      <link>https://dev.to/hommies_fcbf2afe8ddb0c2a7/leetcode-solution-2-add-two-numbers-1k6i</link>
      <guid>https://dev.to/hommies_fcbf2afe8ddb0c2a7/leetcode-solution-2-add-two-numbers-1k6i</guid>
      <description>&lt;h1&gt;
  
  
  Unleash Your Inner Mathematician: Adding Numbers with Linked Lists (LeetCode #2)
&lt;/h1&gt;

&lt;p&gt;Hey awesome developers! 👋 Ever wondered how computers perform basic arithmetic with a twist? Today, we're diving into a classic LeetCode problem that might seem simple on the surface but introduces some fundamental data structures and algorithmic thinking: &lt;strong&gt;"Add Two Numbers"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This problem is a fantastic way to sharpen your skills with &lt;strong&gt;linked lists&lt;/strong&gt; and understand how to simulate everyday operations like addition programmatically. Don't worry if linked lists sound intimidating; we'll break it down piece by piece!&lt;/p&gt;




&lt;h3&gt;
  
  
  📚 Problem Explanation: Digits in Reverse!
&lt;/h3&gt;

&lt;p&gt;Imagine you have two numbers, but instead of seeing them as regular integers like &lt;code&gt;342&lt;/code&gt; or &lt;code&gt;465&lt;/code&gt;, their digits are stored in a special way: a &lt;strong&gt;linked list&lt;/strong&gt;, and in &lt;strong&gt;reverse order&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Each "node" in our linked list holds a single digit. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The number &lt;code&gt;342&lt;/code&gt; would be represented as a linked list: &lt;code&gt;2 -&amp;gt; 4 -&amp;gt; 3&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  The number &lt;code&gt;465&lt;/code&gt; would be: &lt;code&gt;5 -&amp;gt; 6 -&amp;gt; 4&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our mission? To add these two numbers together, digit by digit, and return their sum as &lt;em&gt;another&lt;/em&gt; linked list, also in reverse order.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's look at Example 1:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Input:&lt;/strong&gt; &lt;code&gt;l1 = [2,4,3]&lt;/code&gt; (represents 342)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Input:&lt;/strong&gt; &lt;code&gt;l2 = [5,6,4]&lt;/code&gt; (represents 465)&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Output:&lt;/strong&gt; &lt;code&gt;[7,0,8]&lt;/code&gt; (represents 807)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;See? &lt;code&gt;342 + 465 = 807&lt;/code&gt;. The &lt;code&gt;[7,0,8]&lt;/code&gt; linked list correctly gives us 807 in reverse!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A few important rules:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The lists are &lt;em&gt;non-empty&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;  Digits are non-negative (0-9).&lt;/li&gt;
&lt;li&gt;  No leading zeros (unless the number itself is 0, like &lt;code&gt;[0]&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🤔 Intuition: How Do We Add Numbers By Hand?
&lt;/h3&gt;

&lt;p&gt;Before we jump into code, let's think about how &lt;em&gt;you&lt;/em&gt; add numbers manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  342
+ 465
-----
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Start from the rightmost digits:&lt;/strong&gt; &lt;code&gt;2 + 5 = 7&lt;/code&gt;. Write down &lt;code&gt;7&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Move to the next digits (tens place):&lt;/strong&gt; &lt;code&gt;4 + 6 = 10&lt;/code&gt;. Write down &lt;code&gt;0&lt;/code&gt;, and &lt;strong&gt;carry over&lt;/strong&gt; &lt;code&gt;1&lt;/code&gt; to the hundreds place.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Move to the next digits (hundreds place):&lt;/strong&gt; &lt;code&gt;3 + 4 + (the carried-over 1) = 8&lt;/code&gt;. Write down &lt;code&gt;8&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result is &lt;code&gt;807&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This "digit-by-digit, with a carry-over" strategy is exactly what we'll replicate with our linked lists! Since the digits are already in reverse order, it's like we're already starting from the rightmost digit (the units place)! This is a huge hint.&lt;/p&gt;




&lt;h3&gt;
  
  
  🪜 Approach: Step-by-Step with Linked Lists
&lt;/h3&gt;

&lt;p&gt;Our approach will mimic manual addition:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialize:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Create a &lt;code&gt;dummy&lt;/code&gt; node. This is a common trick in linked list problems. It acts as a placeholder for the head of our new list. We'll eventually return &lt;code&gt;dummy.next&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Create a &lt;code&gt;current&lt;/code&gt; pointer, initialized to &lt;code&gt;dummy&lt;/code&gt;. This pointer will help us build our result list by moving forward.&lt;/li&gt;
&lt;li&gt;  Initialize a &lt;code&gt;carry&lt;/code&gt; variable to &lt;code&gt;0&lt;/code&gt;. This will store any carry-over from the previous sum.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Iterate through the lists:&lt;/strong&gt; We need to keep adding digits as long as there are digits in &lt;em&gt;either&lt;/em&gt; &lt;code&gt;l1&lt;/code&gt; or &lt;code&gt;l2&lt;/code&gt;, or if there's still a &lt;code&gt;carry&lt;/code&gt; left over from a previous addition. This &lt;code&gt;while&lt;/code&gt; loop condition is crucial: &lt;code&gt;while l1 or l2 or carry:&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Calculate the sum for the current position:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Start &lt;code&gt;total_sum&lt;/code&gt; with the &lt;code&gt;carry&lt;/code&gt; from the previous step.&lt;/li&gt;
&lt;li&gt;  If &lt;code&gt;l1&lt;/code&gt; is not &lt;code&gt;None&lt;/code&gt; (meaning there's a digit in the first number), add &lt;code&gt;l1.val&lt;/code&gt; to &lt;code&gt;total_sum&lt;/code&gt; and move &lt;code&gt;l1&lt;/code&gt; to its next node (&lt;code&gt;l1 = l1.next&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  If &lt;code&gt;l2&lt;/code&gt; is not &lt;code&gt;None&lt;/code&gt; (meaning there's a digit in the second number), add &lt;code&gt;l2.val&lt;/code&gt; to &lt;code&gt;total_sum&lt;/code&gt; and move &lt;code&gt;l2&lt;/code&gt; to its next node (&lt;code&gt;l2 = l2.next&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Determine the current digit and new carry:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The digit for our result list at the current position will be &lt;code&gt;total_sum % 10&lt;/code&gt; (the remainder after dividing by 10).&lt;/li&gt;
&lt;li&gt;  The new &lt;code&gt;carry&lt;/code&gt; will be &lt;code&gt;total_sum // 10&lt;/code&gt; (the integer division by 10).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Build the result list:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Create a new &lt;code&gt;ListNode&lt;/code&gt; with the calculated &lt;code&gt;digit&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Append this new node to our result list: &lt;code&gt;current.next = new_node&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Move &lt;code&gt;current&lt;/code&gt; forward to this new node: &lt;code&gt;current = current.next&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Return:&lt;/strong&gt; Once the loop finishes, we've built our entire sum list. Return &lt;code&gt;dummy.next&lt;/code&gt; to get the actual head of the sum list (skipping the initial placeholder &lt;code&gt;dummy&lt;/code&gt; node).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This process continues until both input lists are exhausted AND there's no carry left.&lt;/p&gt;




&lt;h3&gt;
  
  
  💻 Code: Bringing It to Life (Python)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Definition for singly-linked list.
&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;next&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Solution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;addTwoNumbers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;l1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="c1"&gt;# Create a dummy node to simplify handling the head of the result list
&lt;/span&gt;        &lt;span class="n"&gt;dummy_head&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="c1"&gt;# 'current' pointer will build our new linked list
&lt;/span&gt;        &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dummy_head&lt;/span&gt;

        &lt;span class="c1"&gt;# Initialize carry to 0
&lt;/span&gt;        &lt;span class="n"&gt;carry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

        &lt;span class="c1"&gt;# Loop as long as there are digits in either list or a carry exists
&lt;/span&gt;        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;l1&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;carry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# Get the value from l1 (or 0 if l1 is exhausted)
&lt;/span&gt;            &lt;span class="n"&gt;val1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;l1&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
            &lt;span class="c1"&gt;# Get the value from l2 (or 0 if l2 is exhausted)
&lt;/span&gt;            &lt;span class="n"&gt;val2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;

            &lt;span class="c1"&gt;# Calculate the total sum for the current position
&lt;/span&gt;            &lt;span class="n"&gt;total_sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;val1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;val2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;carry&lt;/span&gt;

            &lt;span class="c1"&gt;# Determine the digit for the new node (units place of total_sum)
&lt;/span&gt;            &lt;span class="n"&gt;digit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total_sum&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
            &lt;span class="c1"&gt;# Determine the new carry (tens place of total_sum)
&lt;/span&gt;            &lt;span class="n"&gt;carry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;total_sum&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;

            &lt;span class="c1"&gt;# Create a new node with the calculated digit
&lt;/span&gt;            &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ListNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;digit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="c1"&gt;# Move our 'current' pointer forward to the new node
&lt;/span&gt;            &lt;span class="n"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;

            &lt;span class="c1"&gt;# Move l1 and l2 pointers forward if they are not exhausted
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;l1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;l1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;l2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;l2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;

        &lt;span class="c1"&gt;# The first node (dummy_head) was just a placeholder.
&lt;/span&gt;        &lt;span class="c1"&gt;# The actual result list starts from dummy_head.next.
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;dummy_head&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;next&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  ⏱️ Time &amp;amp; Space Complexity Analysis
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Time Complexity:&lt;/strong&gt; O(max(m, n))&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;m&lt;/code&gt; is the number of nodes in &lt;code&gt;l1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;n&lt;/code&gt; is the number of nodes in &lt;code&gt;l2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  We iterate through both linked lists exactly once. The loop runs for a number of times proportional to the length of the longer list. This makes the time complexity linear with respect to the length of the longer input list.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Space Complexity:&lt;/strong&gt; O(max(m, n))&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  In the worst-case scenario, the resulting linked list can have &lt;code&gt;max(m, n) + 1&lt;/code&gt; nodes (if there's a final carry-over). We are creating a new linked list to store the sum. Therefore, the space complexity is also linear with respect to the length of the longer input list.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🌟 Key Takeaways
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Linked Lists for Arithmetic:&lt;/strong&gt; This problem beautifully demonstrates how linked lists can be used to represent and manipulate numbers, especially useful when dealing with very large numbers that might exceed standard integer types.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The "Dummy Node" Trick:&lt;/strong&gt; Using a &lt;code&gt;dummy_head&lt;/code&gt; node is a super common and effective pattern in linked list problems. It simplifies code by always having a node to attach to, eliminating special checks for an empty result list or when adding the very first node.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Carry Handling:&lt;/strong&gt; Understanding how to manage the &lt;code&gt;carry&lt;/code&gt; digit is fundamental to correctly implementing addition, whether manually or programmatically.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Simulating Manual Processes:&lt;/strong&gt; Many algorithmic problems can be solved by breaking them down into steps that mimic how we would solve them in real life.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This problem is a fantastic stepping stone for more complex linked list manipulations and numerical algorithms. Keep practicing, and you'll be a LeetCode master in no time! Happy coding!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Submission Details:&lt;/strong&gt;&lt;br&gt;
Author Account: p1Hzd8mRM8&lt;br&gt;
Time Published: 2026-05-16 22:27:48&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 1. Two Sum</title>
      <dc:creator>Hommies</dc:creator>
      <pubDate>Sat, 16 May 2026 16:56:40 +0000</pubDate>
      <link>https://dev.to/hommies_fcbf2afe8ddb0c2a7/leetcode-solution-1-two-sum-2eh9</link>
      <guid>https://dev.to/hommies_fcbf2afe8ddb0c2a7/leetcode-solution-1-two-sum-2eh9</guid>
      <description>&lt;h1&gt;
  
  
  The OG LeetCode Challenge: Cracking Two Sum with Python!
&lt;/h1&gt;

&lt;p&gt;Hey there, future coding rockstars! 👋&lt;/p&gt;

&lt;p&gt;Ever wondered what the very first problem on LeetCode is? It's a true classic, a rite of passage for many, and a fantastic way to introduce fundamental data structures and algorithms. Today, we're diving into &lt;strong&gt;Two Sum&lt;/strong&gt;! Don't let the "easy" tag fool you; mastering this problem helps build crucial problem-solving muscles.&lt;/p&gt;

&lt;p&gt;Let's break it down together!&lt;/p&gt;




&lt;h2&gt;
  
  
  🧐 What's the Problem All About? (Problem Explanation)
&lt;/h2&gt;

&lt;p&gt;Imagine you're given a list of numbers, like &lt;code&gt;[2, 7, 11, 15]&lt;/code&gt;, and a specific target number, say &lt;code&gt;9&lt;/code&gt;. Your mission, should you choose to accept it, is to find &lt;em&gt;two different numbers&lt;/em&gt; in that list that add up to your target.&lt;/p&gt;

&lt;p&gt;Once you find them, you don't return the numbers themselves, but their &lt;em&gt;positions&lt;/em&gt; (their "indices") in the original list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Time!&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Input:&lt;/strong&gt; &lt;code&gt;nums = [2, 7, 11, 15]&lt;/code&gt;, &lt;code&gt;target = 9&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Think:&lt;/strong&gt; Can we find two numbers that sum to 9?

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;2 + 7 = 9&lt;/code&gt;! Bingo!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Output:&lt;/strong&gt; &lt;code&gt;[0, 1]&lt;/code&gt; (Because 2 is at index 0, and 7 is at index 1)&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Another Example:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Input:&lt;/strong&gt; &lt;code&gt;nums = [3, 2, 4]&lt;/code&gt;, &lt;code&gt;target = 6&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Think:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;3 + 2 = 5&lt;/code&gt; (Nope)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;3 + 4 = 7&lt;/code&gt; (Nope)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;2 + 4 = 6&lt;/code&gt;! Yes!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Output:&lt;/strong&gt; &lt;code&gt;[1, 2]&lt;/code&gt; (2 is at index 1, 4 is at index 2)&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key things to remember:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  You'll always find &lt;em&gt;exactly one&lt;/em&gt; solution.&lt;/li&gt;
&lt;li&gt;  You can't use the same number twice (e.g., if &lt;code&gt;nums&lt;/code&gt; had &lt;code&gt;3&lt;/code&gt; and &lt;code&gt;target&lt;/code&gt; was &lt;code&gt;6&lt;/code&gt;, you couldn't use the &lt;em&gt;same&lt;/em&gt; &lt;code&gt;3&lt;/code&gt; to make &lt;code&gt;3+3&lt;/code&gt;). If there are two &lt;code&gt;3&lt;/code&gt;s, you use both distinct &lt;code&gt;3&lt;/code&gt;s.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤔 Your "Aha!" Moment (Intuition)
&lt;/h2&gt;

&lt;p&gt;How would you solve this as a human, without a computer?&lt;/p&gt;

&lt;p&gt;You might pick the first number (&lt;code&gt;2&lt;/code&gt; from &lt;code&gt;[2, 7, 11, 15]&lt;/code&gt;), then look at &lt;em&gt;every other number&lt;/em&gt; to see if it adds up to &lt;code&gt;9&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;2 + 7 = 9&lt;/code&gt; (Found it!)&lt;/li&gt;
&lt;li&gt;  If not, you'd try &lt;code&gt;2 + 11&lt;/code&gt;, &lt;code&gt;2 + 15&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  If &lt;code&gt;2&lt;/code&gt; didn't work with any other number, you'd move to the next number (&lt;code&gt;7&lt;/code&gt;) and repeat the process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what we call a &lt;strong&gt;brute-force&lt;/strong&gt; approach. It works, but it can be slow for very long lists. For every number, you're looking at almost all other numbers. If there are &lt;code&gt;N&lt;/code&gt; numbers, you might do &lt;code&gt;N * N&lt;/code&gt; (or &lt;code&gt;N^2&lt;/code&gt;) checks in the worst case. Can we do better?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Smarter Way: What are we &lt;em&gt;really&lt;/em&gt; looking for?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's say we pick a number from our list, &lt;code&gt;nums[i]&lt;/code&gt;. We know we need another number, let's call it &lt;code&gt;complement&lt;/code&gt;, such that:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;nums[i] + complement = target&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This means &lt;code&gt;complement = target - nums[i]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, for each &lt;code&gt;nums[i]&lt;/code&gt; we encounter, we don't need to try &lt;em&gt;every other number&lt;/em&gt;. We just need to quickly check if its &lt;em&gt;specific complement&lt;/em&gt; exists somewhere else in our list.&lt;/p&gt;

&lt;p&gt;How do we check for existence super fast? With a &lt;strong&gt;hash map&lt;/strong&gt; (or a &lt;code&gt;dictionary&lt;/code&gt; in Python)! A hash map allows us to store key-value pairs and look up keys almost instantly.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 The Game Plan (Approach)
&lt;/h2&gt;

&lt;p&gt;We'll use a &lt;strong&gt;two-pass hash map&lt;/strong&gt; approach. This means we'll go through our &lt;code&gt;nums&lt;/code&gt; list twice.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;First Pass: Build the Lookup Table&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We'll create an empty &lt;code&gt;hashmap&lt;/code&gt; (a Python dictionary).&lt;/li&gt;
&lt;li&gt;  We iterate through &lt;code&gt;nums&lt;/code&gt; one time. For each number &lt;code&gt;nums[i]&lt;/code&gt; we see, we'll store it in our &lt;code&gt;hashmap&lt;/code&gt; along with its index &lt;code&gt;i&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  So, our &lt;code&gt;hashmap&lt;/code&gt; will look something like &lt;code&gt;{number: index}&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;  Example &lt;code&gt;nums = [2, 7, 11, 15]&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;  After this pass, &lt;code&gt;hashmap&lt;/code&gt; might be: &lt;code&gt;{2: 0, 7: 1, 11: 2, 15: 3}&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Second Pass: Find the Complement&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Now, we iterate through &lt;code&gt;nums&lt;/code&gt; &lt;em&gt;again&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;  For each number &lt;code&gt;nums[i]&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;  Calculate its &lt;code&gt;complement&lt;/code&gt;: &lt;code&gt;complement = target - nums[i]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Check if this &lt;code&gt;complement&lt;/code&gt; exists as a key in our &lt;code&gt;hashmap&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Crucially&lt;/strong&gt;, we also need to make sure that the index associated with the &lt;code&gt;complement&lt;/code&gt; in the &lt;code&gt;hashmap&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; the current index &lt;code&gt;i&lt;/code&gt;. This prevents us from trying to use the same number twice.&lt;/li&gt;
&lt;li&gt;  If both conditions are met (complement found, and it's a different number), we've found our pair! Return &lt;code&gt;[i, hashmap[complement]]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because the problem guarantees exactly one solution, we know we'll find our answer and return from the function during this second pass.&lt;/p&gt;




&lt;h2&gt;
  
  
  💻 Let's Code!
&lt;/h2&gt;

&lt;p&gt;Here's the Python solution implementing the two-pass hash map approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Solution&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;twoSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="c1"&gt;# Step 1: Initialize a hash map (Python dictionary) to store numbers and their indices
&lt;/span&gt;        &lt;span class="n"&gt;hashmap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; 

        &lt;span class="c1"&gt;# First Pass: Populate the hash map
&lt;/span&gt;        &lt;span class="c1"&gt;# We iterate through the array once to store each number and its index.
&lt;/span&gt;        &lt;span class="c1"&gt;# This makes subsequent lookups much faster.
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
            &lt;span class="n"&gt;hashmap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="c1"&gt;# Store: {number: index}
&lt;/span&gt;
        &lt;span class="c1"&gt;# Second Pass: Find the complement
&lt;/span&gt;        &lt;span class="c1"&gt;# Now, we iterate through the array again. For each number, we calculate
&lt;/span&gt;        &lt;span class="c1"&gt;# what its 'complement' should be to reach the target.
&lt;/span&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
            &lt;span class="n"&gt;complement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;nums&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

            &lt;span class="c1"&gt;# Check if the complement exists in our hash map:
&lt;/span&gt;            &lt;span class="c1"&gt;# - `complement in hashmap`: Is the required complement present in our stored numbers?
&lt;/span&gt;            &lt;span class="c1"&gt;# - `hashmap[complement] != i`: Is the complement not the current number itself (i.e., are their indices different)?
&lt;/span&gt;            &lt;span class="c1"&gt;#   This is important because we can't use the same element twice.
&lt;/span&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;complement&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;hashmap&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;hashmap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;complement&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# If both conditions are true, we found our pair!
&lt;/span&gt;                &lt;span class="c1"&gt;# Return the index of the current number (i) and the index of its complement.
&lt;/span&gt;                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hashmap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;complement&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;

        &lt;span class="c1"&gt;# This line should ideally not be reached based on the problem constraints
&lt;/span&gt;        &lt;span class="c1"&gt;# (which state that exactly one solution exists).
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⏰ Space and Time Efficiency (Complexity Analysis)
&lt;/h2&gt;

&lt;p&gt;Understanding how efficient your code is, especially for large inputs, is a core skill!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Time Complexity: O(n)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The first loop (&lt;code&gt;for i in range(len(nums))&lt;/code&gt;) iterates &lt;code&gt;n&lt;/code&gt; times to populate the hash map. On average, inserting an element into a hash map takes &lt;code&gt;O(1)&lt;/code&gt; time. So, the first pass is &lt;code&gt;O(n)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  The second loop (&lt;code&gt;for i in range(len(nums))&lt;/code&gt;) also iterates &lt;code&gt;n&lt;/code&gt; times. Inside this loop, calculating the &lt;code&gt;complement&lt;/code&gt; is &lt;code&gt;O(1)&lt;/code&gt;, and looking up an element in a hash map takes &lt;code&gt;O(1)&lt;/code&gt; time on average. So, the second pass is also &lt;code&gt;O(n)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Adding them up, &lt;code&gt;O(n) + O(n) = O(2n)&lt;/code&gt;, which simplifies to &lt;strong&gt;O(n)&lt;/strong&gt;. This is much faster than the &lt;code&gt;O(n^2)&lt;/code&gt; brute-force approach!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Space Complexity: O(n)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  In the worst-case scenario, we might have to store all &lt;code&gt;n&lt;/code&gt; numbers and their indices in our &lt;code&gt;hashmap&lt;/code&gt;. Therefore, the space required grows linearly with the number of elements in the input array.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  💡 Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Hash Maps are Your Friends:&lt;/strong&gt; For problems involving quick lookups or checking for the existence of elements, hash maps (dictionaries) are incredibly powerful. They can transform a slow &lt;code&gt;O(n)&lt;/code&gt; lookup into an average &lt;code&gt;O(1)&lt;/code&gt; operation!&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Think Complements:&lt;/strong&gt; Many problems can be simplified by rephrasing what you're looking for. Instead of "find two numbers that sum to X", think "for each number, find its 'complement' (X - number)".&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Optimize Iterations:&lt;/strong&gt; While a brute-force approach (nested loops, &lt;code&gt;O(n^2)&lt;/code&gt;) might be your first thought, always consider if you can reduce the number of passes or operations using a suitable data structure.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This problem, despite being "easy," introduces you to a fundamental pattern used in many more complex LeetCode challenges. Keep practicing, and you'll be solving harder problems in no time!&lt;/p&gt;

&lt;p&gt;Happy coding! ✨&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Author Account: p1Hzd8mRM8&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Publishing Time: 2026-05-16 22:26:22&lt;/em&gt;&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
