<?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: Vansh Aggarwal</title>
    <description>The latest articles on DEV Community by Vansh Aggarwal (@vansh_aggarwal_5fb2fff667).</description>
    <link>https://dev.to/vansh_aggarwal_5fb2fff667</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%2F3840143%2F0a808966-4b40-40a8-9beb-f30de0fa323d.png</url>
      <title>DEV Community: Vansh Aggarwal</title>
      <link>https://dev.to/vansh_aggarwal_5fb2fff667</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vansh_aggarwal_5fb2fff667"/>
    <language>en</language>
    <item>
      <title>LeetCode Solution: 1323. Maximum 69 Number</title>
      <dc:creator>Vansh Aggarwal</dc:creator>
      <pubDate>Sun, 12 Apr 2026 17:30:53 +0000</pubDate>
      <link>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-1323-maximum-69-number-35g8</link>
      <guid>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-1323-maximum-69-number-35g8</guid>
      <description>&lt;h1&gt;
  
  
  Maximize Your Number: The "Maximum 69 Number" Challenge Explained!
&lt;/h1&gt;

&lt;p&gt;Hey fellow coders! 👋 Vansh2710 here, ready to dive into another fun LeetCode problem that's perfect for beginners but offers a great lesson in greedy thinking. Today, we're tackling problem &lt;strong&gt;1323: Maximum 69 Number&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Don't let the name scare you! This problem is quite approachable and teaches a fundamental concept in algorithm design. Let's break it down together!&lt;/p&gt;




&lt;h2&gt;
  
  
  🧐 Problem Explanation: What are we trying to do?
&lt;/h2&gt;

&lt;p&gt;Imagine you have a positive integer, but here's the twist: it &lt;strong&gt;only&lt;/strong&gt; consists of the digits &lt;code&gt;6&lt;/code&gt; and &lt;code&gt;9&lt;/code&gt;. For example, &lt;code&gt;9669&lt;/code&gt;, &lt;code&gt;9996&lt;/code&gt;, or &lt;code&gt;66&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Your goal is to make this number as large as possible. You have &lt;em&gt;one special power&lt;/em&gt;: you can change &lt;strong&gt;at most one&lt;/strong&gt; digit. This means you can either:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Change a &lt;code&gt;6&lt;/code&gt; to a &lt;code&gt;9&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Change a &lt;code&gt;9&lt;/code&gt; to a &lt;code&gt;6&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Or, choose not to change anything at all if it makes the number smaller.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After making your &lt;em&gt;single&lt;/em&gt; optimal change (or no change), you need to return the largest possible number.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's look at an example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;num = 9669&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Change the first &lt;code&gt;9&lt;/code&gt; to &lt;code&gt;6&lt;/code&gt; -&amp;gt; &lt;code&gt;6669&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Change the first &lt;code&gt;6&lt;/code&gt; to &lt;code&gt;9&lt;/code&gt; -&amp;gt; &lt;code&gt;9969&lt;/code&gt;  &lt;strong&gt;&amp;lt;-- This looks good!&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;  Change the second &lt;code&gt;6&lt;/code&gt; to &lt;code&gt;9&lt;/code&gt; -&amp;gt; &lt;code&gt;9699&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Change the last &lt;code&gt;9&lt;/code&gt; to &lt;code&gt;6&lt;/code&gt; -&amp;gt; &lt;code&gt;9666&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Comparing all these, &lt;code&gt;9969&lt;/code&gt; is clearly the maximum.&lt;/p&gt;

&lt;p&gt;See? Simple, right? Now, how do we find that "maximum" every time?&lt;/p&gt;




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

&lt;p&gt;When you want to make a number as large as possible, what digits do you usually want in it? &lt;strong&gt;Larger digits!&lt;/strong&gt; And where do those larger digits have the most impact? At the &lt;strong&gt;leftmost&lt;/strong&gt; positions (highest place values).&lt;/p&gt;

&lt;p&gt;Think about it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Changing &lt;code&gt;600&lt;/code&gt; to &lt;code&gt;900&lt;/code&gt; increases the number by &lt;code&gt;300&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Changing &lt;code&gt;006&lt;/code&gt; to &lt;code&gt;009&lt;/code&gt; increases the number by &lt;code&gt;3&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The digit furthest to the left (the "most significant" digit) contributes the most to the number's overall value.&lt;/p&gt;

&lt;p&gt;So, if we have the power to change &lt;em&gt;at most one&lt;/em&gt; digit, and we want to maximize the number, what's the best change we can make?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; We definitely don't want to change a &lt;code&gt;9&lt;/code&gt; to a &lt;code&gt;6&lt;/code&gt;, because &lt;code&gt;6&lt;/code&gt; is smaller than &lt;code&gt;9&lt;/code&gt;, and that would always make our number smaller.&lt;/li&gt;
&lt;li&gt; Therefore, our only useful change is to convert a &lt;code&gt;6&lt;/code&gt; into a &lt;code&gt;9&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, if there are multiple &lt;code&gt;6&lt;/code&gt;s, which one should we change? To maximize the number, we should change the &lt;code&gt;6&lt;/code&gt; that is furthest to the &lt;strong&gt;left&lt;/strong&gt;. Why? Because changing &lt;code&gt;6&lt;/code&gt; to &lt;code&gt;9&lt;/code&gt; in the hundreds place (&lt;code&gt;6xx&lt;/code&gt; to &lt;code&gt;9xx&lt;/code&gt;) makes a much bigger difference than changing it in the ones place (&lt;code&gt;xx6&lt;/code&gt; to &lt;code&gt;xx9&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The "Aha!": To get the maximum number, find the &lt;em&gt;first&lt;/em&gt; (leftmost) &lt;code&gt;6&lt;/code&gt; and change it to a &lt;code&gt;9&lt;/code&gt;. If there are no &lt;code&gt;6&lt;/code&gt;s, the number is already all &lt;code&gt;9&lt;/code&gt;s, so no change is needed.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🪜 Approach: Step-by-Step Logic
&lt;/h2&gt;

&lt;p&gt;Let's translate that intuition into a concrete plan:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Convert to String:&lt;/strong&gt; It's much easier to manipulate individual digits when the number is a string. If &lt;code&gt;num&lt;/code&gt; is an integer, convert it into a string or character array. For example, &lt;code&gt;9669&lt;/code&gt; becomes &lt;code&gt;"9669"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Iterate and Find:&lt;/strong&gt; Go through the digits of the string from left to right (from the beginning of the string).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The First '6' is Key:&lt;/strong&gt; The very first time you find a character &lt;code&gt;'6'&lt;/code&gt;, that's your target! Change that &lt;code&gt;'6'&lt;/code&gt; to a &lt;code&gt;'9'&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;One Change Only:&lt;/strong&gt; Since you can change &lt;em&gt;at most one&lt;/em&gt; digit, once you've made this change, you're done! You've found the optimal modification. You can stop iterating.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Convert Back:&lt;/strong&gt; Convert the modified string back into an integer. This will be your maximum number.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Edge Case (No '6's):&lt;/strong&gt; What if you iterate through the entire string and never find a &lt;code&gt;'6'&lt;/code&gt;? This means the original number was already all &lt;code&gt;9&lt;/code&gt;s (like &lt;code&gt;9999&lt;/code&gt;). In this case, you wouldn't have made any changes, and the original number (now as a string, then converted back to int) is already the maximum.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  💻 Code
&lt;/h2&gt;

&lt;p&gt;Let's implement this in C. We'll use &lt;code&gt;sprintf&lt;/code&gt; to convert the integer to a string, modify the string, and then &lt;code&gt;atoi&lt;/code&gt; to convert it back.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;  // Required for sprintf and printf (for testing)&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt; // Required for strlen&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt; // Required for atoi&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;maximum69Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// 1. Convert the integer to a string (character array).&lt;/span&gt;
    &lt;span class="c1"&gt;// Constraints: 1 &amp;lt;= num &amp;lt;= 10^4.&lt;/span&gt;
    &lt;span class="c1"&gt;// 10^4 has 5 digits. We need space for 5 digits + null terminator.&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;num_str&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; 
    &lt;span class="n"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"%d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. Iterate through the string to find the first '6'.&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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;0&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;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;len&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 3. If a '6' is found, change it to '9'.&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_str&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="sc"&gt;'6'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;num_str&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="sc"&gt;'9'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="c1"&gt;// 4. We can only make at most one change, so break after the first optimal change.&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 5. Convert the modified string back to an integer and return.&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;atoi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&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;Let &lt;code&gt;N&lt;/code&gt; be the number of digits in &lt;code&gt;num&lt;/code&gt;. Given the constraint &lt;code&gt;1 &amp;lt;= num &amp;lt;= 10^4&lt;/code&gt;, &lt;code&gt;N&lt;/code&gt; will be at most 5 digits.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Time Complexity:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;sprintf(num_str, "%d", num)&lt;/code&gt;: Converting an integer to a string takes time proportional to the number of digits, &lt;code&gt;O(N)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;strlen(num_str)&lt;/code&gt;: Calculating string length is &lt;code&gt;O(N)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  The &lt;code&gt;for&lt;/code&gt; loop iterates through the string at most &lt;code&gt;N&lt;/code&gt; times. In the worst case, we might iterate through all digits (if the '6' is the last digit, or if there are no '6's). So, this is &lt;code&gt;O(N)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;atoi(num_str)&lt;/code&gt;: Converting a string back to an integer also takes time proportional to its length, &lt;code&gt;O(N)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Since &lt;code&gt;N&lt;/code&gt; is very small and constant (at most 5), the overall time complexity is essentially &lt;strong&gt;O(1)&lt;/strong&gt; (constant time).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Space Complexity:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We create a character array &lt;code&gt;num_str&lt;/code&gt; to store the string representation of &lt;code&gt;num&lt;/code&gt;. The size of this array is proportional to the number of digits &lt;code&gt;N&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Since &lt;code&gt;N&lt;/code&gt; is constant (at most 5), the space complexity is also &lt;strong&gt;O(1)&lt;/strong&gt; (constant space).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This solution is highly efficient for the given constraints!&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Greedy Approach:&lt;/strong&gt; For maximization problems, a greedy strategy often works. Here, making the locally optimal choice (changing the leftmost &lt;code&gt;6&lt;/code&gt; to &lt;code&gt;9&lt;/code&gt;) leads to the globally optimal solution.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Digit Manipulation:&lt;/strong&gt; When you need to work with individual digits of a number, converting it to a string is a common and often convenient technique. Just remember to convert it back!&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Place Value Matters:&lt;/strong&gt; Always remember how place value impacts a number's magnitude. Changes to digits on the left have a much greater effect.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;I hope this explanation made the "Maximum 69 Number" problem clear and helped you understand the thought process behind solving it! Happy coding!&lt;/p&gt;




&lt;p&gt;Authored by Vansh2710&lt;br&gt;&lt;br&gt;
Published: 2026-04-12 23:00:33&lt;/p&gt;




</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 2264. Largest 3-Same-Digit Number in String</title>
      <dc:creator>Vansh Aggarwal</dc:creator>
      <pubDate>Sun, 12 Apr 2026 17:20:39 +0000</pubDate>
      <link>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-2264-largest-3-same-digit-number-in-string-1eb9</link>
      <guid>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-2264-largest-3-same-digit-number-in-string-1eb9</guid>
      <description>&lt;h1&gt;
  
  
  Uncovering Triple Trouble: Finding the Largest 'Good' Number in Your String!
&lt;/h1&gt;

&lt;p&gt;Hey everyone! 👋 Vansh here, ready to dive into another fun LeetCode challenge that's perfect for beginners but offers some neat insights. Today, we're tackling problem 2264: "Largest 3-Same-Digit Number in String." Don't let the long name scare you; this one is super approachable and a great way to flex your string manipulation muscles!&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: What's a "Good" Number Anyway?
&lt;/h2&gt;

&lt;p&gt;Imagine you're given a really long number as a string, like &lt;code&gt;"6777133339"&lt;/code&gt;. Your goal is to find special little segments within this string. We call these segments "good integers" if they meet two simple rules:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Length 3:&lt;/strong&gt; They must be exactly three characters long.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Same Digit:&lt;/strong&gt; All three characters must be the exact same digit. Think &lt;code&gt;"777"&lt;/code&gt;, &lt;code&gt;"333"&lt;/code&gt;, or even &lt;code&gt;"000"&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your task is to find all such "good integers" and then return the &lt;em&gt;largest&lt;/em&gt; one among them. If there are no good integers at all, you should just return an empty string &lt;code&gt;""&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick Examples to clarify:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Input: &lt;code&gt;num = "6777133339"&lt;/code&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;"777"&lt;/code&gt; is a good integer.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;"333"&lt;/code&gt; is another good integer.&lt;/li&gt;
&lt;li&gt;  Between "777" and "333", "777" is larger. So, the output is &lt;code&gt;"777"&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Input: &lt;code&gt;num = "2300019"&lt;/code&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;"000"&lt;/code&gt; is the only good integer. Output: &lt;code&gt;"000"&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  &lt;strong&gt;Input: &lt;code&gt;num = "42352338"&lt;/code&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  No three consecutive identical digits exist. Output: &lt;code&gt;""&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;A small but important note: leading zeros are totally fine! &lt;code&gt;"000"&lt;/code&gt; is a valid good integer.&lt;/p&gt;

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

&lt;p&gt;When I first read this problem, my brain immediately went to: "Okay, I need to look for patterns of three identical characters." Since we're dealing with a string, the most straightforward way to do this is to simply &lt;em&gt;slide&lt;/em&gt; a window of size 3 across the string.&lt;/p&gt;

&lt;p&gt;Imagine a magnifying glass that can only see three characters at a time. You start at the beginning, check those three. Then, you slide it one position to the right, check those three, and so on, until you reach the end of the string.&lt;/p&gt;

&lt;p&gt;Every time our magnifying glass shows three identical digits (like &lt;code&gt;[7, 7, 7]&lt;/code&gt;), we've found a "good integer." Now, how do we find the &lt;em&gt;largest&lt;/em&gt; one? Since we're comparing numbers like "999" vs "888" vs "000", and they're all represented as 3-digit strings, comparing them lexicographically (alphabetically, essentially) will work perfectly! "999" is indeed "greater" than "888" in string comparison. This simplifies things a lot!&lt;/p&gt;

&lt;h2&gt;
  
  
  Approach: Step-by-Step Logic
&lt;/h2&gt;

&lt;p&gt;Let's break down the strategy into clear, executable steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialize a &lt;code&gt;best&lt;/code&gt; variable:&lt;/strong&gt; We'll need a way to keep track of the largest good integer we've found so far. Let's start it as an empty string (&lt;code&gt;""&lt;/code&gt;). This serves two purposes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  It acts as a placeholder for when no good integers have been found yet.&lt;/li&gt;
&lt;li&gt;  If no good integers are ever found, this &lt;code&gt;""&lt;/code&gt; will be our final return value, as required by the problem.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Iterate through the string:&lt;/strong&gt; We need to check every possible substring of length 3. If &lt;code&gt;num&lt;/code&gt; has &lt;code&gt;N&lt;/code&gt; characters, and we're looking at &lt;code&gt;num[i]&lt;/code&gt;, &lt;code&gt;num[i+1]&lt;/code&gt;, and &lt;code&gt;num[i+2]&lt;/code&gt;, then the index &lt;code&gt;i&lt;/code&gt; can go from &lt;code&gt;0&lt;/code&gt; all the way up to &lt;code&gt;N-3&lt;/code&gt;. Why &lt;code&gt;N-3&lt;/code&gt;? Because if &lt;code&gt;i&lt;/code&gt; is &lt;code&gt;N-3&lt;/code&gt;, then &lt;code&gt;i+2&lt;/code&gt; would be &lt;code&gt;N-1&lt;/code&gt;, which is the last character of the string. We can't go any further than that!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Check for "goodness":&lt;/strong&gt; Inside our loop, for each &lt;code&gt;i&lt;/code&gt;, we'll check if &lt;code&gt;num[i]&lt;/code&gt;, &lt;code&gt;num[i+1]&lt;/code&gt;, and &lt;code&gt;num[i+2]&lt;/code&gt; are all the same. This means &lt;code&gt;num[i] == num[i+1]&lt;/code&gt; AND &lt;code&gt;num[i+1] == num[i+2]&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Update &lt;code&gt;best&lt;/code&gt;:&lt;/strong&gt; If we find a "good" integer (i.e., the condition in step 3 is true):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Extract this 3-character substring. Let's call it &lt;code&gt;currentGood&lt;/code&gt;. (e.g., &lt;code&gt;num.substr(i, 3)&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  Compare &lt;code&gt;currentGood&lt;/code&gt; with our &lt;code&gt;best&lt;/code&gt; good integer found so far. We can use the &lt;code&gt;max()&lt;/code&gt; function for strings. &lt;code&gt;best = max(best, currentGood)&lt;/code&gt;. This will automatically pick the lexicographically (and numerically, in this case) larger string. If &lt;code&gt;best&lt;/code&gt; is &lt;code&gt;""&lt;/code&gt;, the first &lt;code&gt;currentGood&lt;/code&gt; will become &lt;code&gt;best&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;best&lt;/code&gt;:&lt;/strong&gt; After the loop finishes checking all possible substrings, our &lt;code&gt;best&lt;/code&gt; variable will hold the largest good integer, or &lt;code&gt;""&lt;/code&gt; if none were found. Simply return it!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Code (C++)
&lt;/h2&gt;

&lt;p&gt;Here's the elegant C++ solution embodying this approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&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="nl"&gt;public:&lt;/span&gt;
    &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;largestGoodInteger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Initialize an empty string to store the largest good integer found&lt;/span&gt;

        &lt;span class="c1"&gt;// Iterate through the string, stopping 2 characters before the end&lt;/span&gt;
        &lt;span class="c1"&gt;// because we need a substring of length 3 (num[i], num[i+1], num[i+2])&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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;0&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;2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Check if the current character and the next two are identical&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&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;num&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="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;num&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;num&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;2&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// If they are, we found a "good" integer.&lt;/span&gt;
                &lt;span class="c1"&gt;// Extract this 3-digit substring.&lt;/span&gt;
                &lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;currentGood&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;substr&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="c1"&gt;// Compare it with our 'best' found so far.&lt;/span&gt;
                &lt;span class="c1"&gt;// Since 'best' starts empty, the first good integer will be assigned.&lt;/span&gt;
                &lt;span class="c1"&gt;// For subsequent good integers, 'max' will correctly pick the numerically larger one&lt;/span&gt;
                &lt;span class="c1"&gt;// because string comparison works lexicographically (e.g., "999" &amp;gt; "888").&lt;/span&gt;
                &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currentGood&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Return the largest good integer found, or "" if none existed.&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&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;Let's break down how efficient our solution is:&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;  We iterate through the &lt;code&gt;num&lt;/code&gt; string exactly once using a &lt;code&gt;for&lt;/code&gt; loop.&lt;/li&gt;
&lt;li&gt;  Inside the loop, operations like character comparisons (&lt;code&gt;num[i] == num[i+1]&lt;/code&gt;) and &lt;code&gt;substr(i, 3)&lt;/code&gt; (which extracts a fixed-length 3 substring) take constant time, O(1).&lt;/li&gt;
&lt;li&gt;  The &lt;code&gt;max(best, currentGood)&lt;/code&gt; operation also compares two fixed-length 3 strings, taking O(1) time.&lt;/li&gt;
&lt;li&gt;  Therefore, the total time complexity is directly proportional to the length of the input string &lt;code&gt;num&lt;/code&gt;. If &lt;code&gt;N&lt;/code&gt; is the length of &lt;code&gt;num&lt;/code&gt;, it's O(N). This is excellent!&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 use a few extra variables: &lt;code&gt;best&lt;/code&gt; and &lt;code&gt;currentGood&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Both &lt;code&gt;best&lt;/code&gt; and &lt;code&gt;currentGood&lt;/code&gt; strings are always of a maximum length of 3. This means the amount of extra memory we use is constant, regardless of how long the input string &lt;code&gt;num&lt;/code&gt; is.&lt;/li&gt;
&lt;li&gt;  Hence, the space complexity is O(1). This is as good as it gets!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

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

&lt;p&gt;This problem, while seemingly simple, reinforces some fundamental programming concepts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Sliding Window:&lt;/strong&gt; It's a classic technique for problems that involve inspecting contiguous subsequences or substrings of a fixed size.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;String Comparison:&lt;/strong&gt; For numbers represented as strings of the &lt;em&gt;same length&lt;/em&gt;, lexicographical comparison (&lt;code&gt;max&lt;/code&gt; or &lt;code&gt;&amp;gt;&lt;/code&gt; operators) works perfectly to find the numerically largest value.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Edge Case Handling:&lt;/strong&gt; Initializing &lt;code&gt;best&lt;/code&gt; to &lt;code&gt;""&lt;/code&gt; elegantly handles the case where no "good" integers are found.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Simplicity Wins:&lt;/strong&gt; Sometimes, the most straightforward approach is also the most optimal. No complex data structures or algorithms needed here!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I hope this walkthrough helped you understand and appreciate this LeetCode problem! Happy coding!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Author Account: Vansh2710&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Published: 2026-04-12 22:50:06&lt;/em&gt;&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 326. Power of Three</title>
      <dc:creator>Vansh Aggarwal</dc:creator>
      <pubDate>Thu, 09 Apr 2026 18:13:55 +0000</pubDate>
      <link>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-326-power-of-three-4i6i</link>
      <guid>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-326-power-of-three-4i6i</guid>
      <description>&lt;h1&gt;
  
  
  Cracking the Code: Is It a Power of Three? (LeetCode 326 Deep Dive!) 🤯
&lt;/h1&gt;

&lt;p&gt;Hey there, future coding legends! 👋 Vansh2710 here, ready to tackle another fun LeetCode challenge that might seem simple on the surface but has some neat tricks up its sleeve. Today, we're diving into &lt;strong&gt;Problem 326: Power of Three&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This problem is a fantastic way to practice handling edge cases, understanding numerical properties, and even thinking about optimization. Let's get started!&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: What Exactly Are We Looking For? 🤔
&lt;/h2&gt;

&lt;p&gt;We're given an integer &lt;code&gt;n&lt;/code&gt;. Our task is to determine if &lt;code&gt;n&lt;/code&gt; is a "power of three."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does "power of three" mean?&lt;/strong&gt;&lt;br&gt;
It means &lt;code&gt;n&lt;/code&gt; can be expressed as &lt;code&gt;3&lt;/code&gt; raised to some integer exponent &lt;code&gt;x&lt;/code&gt; (i.e., &lt;code&gt;n == 3^x&lt;/code&gt;).&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Example 1: &lt;code&gt;n = 27&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Is &lt;code&gt;27&lt;/code&gt; a power of three? Yes! &lt;code&gt;27 = 3 * 3 * 3 = 3^3&lt;/code&gt;. So, we should return &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Example 2: &lt;code&gt;n = 0&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Is &lt;code&gt;0&lt;/code&gt; a power of three? No. There's no exponent &lt;code&gt;x&lt;/code&gt; for which &lt;code&gt;3^x&lt;/code&gt; equals &lt;code&gt;0&lt;/code&gt;. &lt;code&gt;3^0 = 1&lt;/code&gt;, &lt;code&gt;3^1 = 3&lt;/code&gt;, &lt;code&gt;3^-1 = 1/3&lt;/code&gt;, etc. So, we should return &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Example 3: &lt;code&gt;n = -1&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Is &lt;code&gt;-1&lt;/code&gt; a power of three? No. Powers of positive numbers (like 3) are always positive. So, we should return &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Constraints:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;n&lt;/code&gt; will be between &lt;code&gt;-2^31&lt;/code&gt; and &lt;code&gt;2^31 - 1&lt;/code&gt;. This is the typical range for a 32-bit signed integer.&lt;/p&gt;


&lt;h2&gt;
  
  
  The "Aha!" Moment: How Do We Spot a Power of Three? ✨
&lt;/h2&gt;

&lt;p&gt;Imagine you have a number, say &lt;code&gt;81&lt;/code&gt;. How would you manually check if it's a power of three?&lt;/p&gt;

&lt;p&gt;You'd probably do something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Is &lt;code&gt;81&lt;/code&gt; divisible by &lt;code&gt;3&lt;/code&gt;? Yes, &lt;code&gt;81 / 3 = 27&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Is &lt;code&gt;27&lt;/code&gt; divisible by &lt;code&gt;3&lt;/code&gt;? Yes, &lt;code&gt;27 / 3 = 9&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Is &lt;code&gt;9&lt;/code&gt; divisible by &lt;code&gt;3&lt;/code&gt;? Yes, &lt;code&gt;9 / 3 = 3&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Is &lt;code&gt;3&lt;/code&gt; divisible by &lt;code&gt;3&lt;/code&gt;? Yes, &lt;code&gt;3 / 3 = 1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; We reached &lt;code&gt;1&lt;/code&gt;! This means &lt;code&gt;81&lt;/code&gt; is indeed a power of three (&lt;code&gt;3^4&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What if we had &lt;code&gt;28&lt;/code&gt;?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Is &lt;code&gt;28&lt;/code&gt; divisible by &lt;code&gt;3&lt;/code&gt;? No! &lt;code&gt;28 % 3 = 1&lt;/code&gt;.
Since we can't divide it evenly by 3 and reach 1, &lt;code&gt;28&lt;/code&gt; is not a power of three.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This repeated division gives us a strong hint! However, instead of repeatedly &lt;em&gt;dividing&lt;/em&gt;, we can also &lt;em&gt;multiply&lt;/em&gt; powers of three and see if we hit &lt;code&gt;n&lt;/code&gt;. This is the intuition behind the provided solution. We'll start with &lt;code&gt;1&lt;/code&gt; (which is &lt;code&gt;3^0&lt;/code&gt;) and keep multiplying by &lt;code&gt;3&lt;/code&gt;, checking if we ever reach &lt;code&gt;n&lt;/code&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Step-by-Step Approach 🚀
&lt;/h2&gt;

&lt;p&gt;Let's break down the strategy used in the solution:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Handle Non-Positive Numbers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  As seen in Example 2 (&lt;code&gt;n=0&lt;/code&gt;) and Example 3 (&lt;code&gt;n=-1&lt;/code&gt;), any number less than or equal to &lt;code&gt;0&lt;/code&gt; cannot be a power of three. So, our very first check should be: &lt;code&gt;if (n &amp;lt;= 0) return false;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Handle the Base Case (n = 1):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;1&lt;/code&gt; is &lt;code&gt;3^0&lt;/code&gt;. It's a power of three. So, &lt;code&gt;if (n == 1) return true;&lt;/code&gt;. This is an important edge case to handle explicitly to avoid issues in the multiplication loop.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Iterative Multiplication:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We need a variable, let's call it &lt;code&gt;res&lt;/code&gt; (for "result"), to store increasing powers of three. Initialize &lt;code&gt;res = 1&lt;/code&gt; (since &lt;code&gt;3^0 = 1&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  Now, we'll start a loop. In each iteration, we multiply &lt;code&gt;res&lt;/code&gt; by &lt;code&gt;3&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  After each multiplication, we check if &lt;code&gt;res&lt;/code&gt; is equal to &lt;code&gt;n&lt;/code&gt;. If it is, &lt;code&gt;n&lt;/code&gt; is a power of three, and we can immediately return &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Why &lt;code&gt;long long&lt;/code&gt; for &lt;code&gt;res&lt;/code&gt; and a loop for &lt;code&gt;30&lt;/code&gt; iterations?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The maximum &lt;code&gt;int&lt;/code&gt; value is &lt;code&gt;2^31 - 1&lt;/code&gt; (approx &lt;code&gt;2 * 10^9&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  The largest power of three that fits in a positive &lt;code&gt;int&lt;/code&gt; is &lt;code&gt;3^19 = 1,162,261,467&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;3^20&lt;/code&gt; would already exceed &lt;code&gt;2^31 - 1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  To avoid potential overflow issues if &lt;code&gt;n&lt;/code&gt; is large (and &lt;code&gt;res&lt;/code&gt; &lt;em&gt;might&lt;/em&gt; temporarily exceed &lt;code&gt;int&lt;/code&gt; max before matching &lt;code&gt;n&lt;/code&gt;), it's safer to use &lt;code&gt;long long&lt;/code&gt; for &lt;code&gt;res&lt;/code&gt;. This ensures &lt;code&gt;res&lt;/code&gt; can hold values beyond the &lt;code&gt;int&lt;/code&gt; range if needed.&lt;/li&gt;
&lt;li&gt;  A loop running &lt;code&gt;30&lt;/code&gt; times is sufficient because &lt;code&gt;3^19&lt;/code&gt; is the largest relevant power. We don't need to go much further, and &lt;code&gt;3^30&lt;/code&gt; would certainly exceed &lt;code&gt;long long&lt;/code&gt; max &lt;em&gt;if&lt;/em&gt; we were to keep calculating without checking &lt;code&gt;res &amp;gt; n&lt;/code&gt; (which isn't strictly necessary here because we check &lt;code&gt;n == res&lt;/code&gt; and &lt;code&gt;n&lt;/code&gt; is an int). The &lt;code&gt;30&lt;/code&gt; iterations are a safe upper bound.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;No Match Found:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If the loop finishes without &lt;code&gt;n&lt;/code&gt; ever matching &lt;code&gt;res&lt;/code&gt;, it means &lt;code&gt;n&lt;/code&gt; is not a power of three. We then return &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;


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

&lt;p&gt;Here's the complete C++ solution, based on the structure we discussed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&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="nl"&gt;public:&lt;/span&gt;
    &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;isPowerOfThree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Step 1: Handle non-positive numbers&lt;/span&gt;
        &lt;span class="k"&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;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Step 2: Handle the base case n = 1 (3^0)&lt;/span&gt;
        &lt;span class="k"&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Step 3 &amp;amp; 4: Iterative multiplication and check for match&lt;/span&gt;
        &lt;span class="c1"&gt;// Use long long for 'res' to safely store larger powers of three&lt;/span&gt;
        &lt;span class="c1"&gt;// before comparison, preventing potential overflow issues if n is large.&lt;/span&gt;
        &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;res&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;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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;0&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;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;30&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// 3^19 is largest power fitting in int, 30 iterations is safe&lt;/span&gt;
            &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Calculate the next power of three&lt;/span&gt;

            &lt;span class="c1"&gt;// If current power of three matches n, we found our answer!&lt;/span&gt;
            &lt;span class="k"&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;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;// Optimization: If 'res' becomes larger than 'n', &lt;/span&gt;
            &lt;span class="c1"&gt;// 'n' cannot be a power of three because powers of three only grow.&lt;/span&gt;
            &lt;span class="c1"&gt;// This also helps prevent 'res' from overflowing if n is not a power of 3.&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Step 5: If loop completes without a match, n is not a power of three&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&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;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Time Complexity: O(1)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Why O(1)? The loop runs a &lt;em&gt;fixed&lt;/em&gt; maximum number of times (30 iterations). It does not depend on the input &lt;code&gt;n&lt;/code&gt; in a way that scales with &lt;code&gt;n&lt;/code&gt; (e.g., &lt;code&gt;n&lt;/code&gt; itself is not the loop bound). Performing a fixed number of operations means constant time complexity.&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 use a few variables (&lt;code&gt;n&lt;/code&gt;, &lt;code&gt;res&lt;/code&gt;, &lt;code&gt;i&lt;/code&gt;) which take up a constant amount of memory regardless of the input value &lt;code&gt;n&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




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

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Edge Cases are Crucial:&lt;/strong&gt; Always consider &lt;code&gt;0&lt;/code&gt;, negative numbers, and the smallest positive case (&lt;code&gt;1&lt;/code&gt; for powers of three).&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Iterative Solutions:&lt;/strong&gt; For problems involving powers, repeated multiplication or division is a very common and effective pattern.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Preventing Overflow:&lt;/strong&gt; Be mindful of integer limits. Using &lt;code&gt;long long&lt;/code&gt; for intermediate calculations when dealing with potentially large numbers (like &lt;code&gt;res * 3&lt;/code&gt;) can save you from subtle bugs.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Constant Time is Awesome:&lt;/strong&gt; When you can solve a problem in &lt;code&gt;O(1)&lt;/code&gt; time, you've done a great job!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This problem also has a fascinating "Follow up" question: "Could you solve it without loops/recursion?" This hints at mathematical properties (like using &lt;code&gt;log&lt;/code&gt; functions) or leveraging the fact that the largest power of 3 that fits in an &lt;code&gt;int&lt;/code&gt; is a known constant. We'll leave that as a thought exercise for another day! 😉&lt;/p&gt;

&lt;p&gt;Hope this breakdown helped you understand LeetCode 326 better! Happy coding!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Authored by Vansh2710. Published on 2026-04-09 23:43:07.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 118. Pascal's Triangle</title>
      <dc:creator>Vansh Aggarwal</dc:creator>
      <pubDate>Tue, 07 Apr 2026 18:29:40 +0000</pubDate>
      <link>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-118-pascals-triangle-n19</link>
      <guid>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-118-pascals-triangle-n19</guid>
      <description>&lt;h1&gt;
  
  
  Demystifying Pascal's Triangle: A Beginner's Guide to LeetCode 118
&lt;/h1&gt;

&lt;p&gt;Hey there, aspiring coders and problem-solvers! 👋 Today, we're going to dive into a classic and elegant LeetCode problem that's perfect for beginners: &lt;strong&gt;118. Pascal's Triangle&lt;/strong&gt;. Don't let the mathematical name intimidate you – this problem is a fantastic way to build your foundational algorithmic skills, especially with array manipulation and understanding patterns.&lt;/p&gt;

&lt;p&gt;So, grab your favorite beverage, get comfortable, and let's unravel the beauty of Pascal's Triangle together!&lt;/p&gt;




&lt;h3&gt;
  
  
  The Problem: Building a Beautiful Triangle
&lt;/h3&gt;

&lt;p&gt;The problem statement asks us to generate the first &lt;code&gt;numRows&lt;/code&gt; of Pascal's Triangle.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Pascal's Triangle?&lt;/strong&gt;&lt;br&gt;
It's a triangular array of numbers where:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; The first and last numbers in each row are always &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Every other number in a row is the sum of the two numbers directly above it from the previous row.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's look at an example to make this crystal clear:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1:&lt;/strong&gt;&lt;br&gt;
Input: &lt;code&gt;numRows = 5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;
     &lt;span class="p"&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;// Row 0&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&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;// Row 1&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&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;// Row 2&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&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;// Row 3&lt;/span&gt;
 &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&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;// Row 4&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See how &lt;code&gt;2&lt;/code&gt; (in Row 2) is &lt;code&gt;1 + 1&lt;/code&gt; from Row 1? And &lt;code&gt;3&lt;/code&gt; (in Row 3) is &lt;code&gt;1 + 2&lt;/code&gt; or &lt;code&gt;2 + 1&lt;/code&gt; from Row 2? That's the core rule!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constraints:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;1 &amp;lt;= numRows &amp;lt;= 30&lt;/code&gt; (This means we don't have to worry about super large inputs, which is nice for a beginner problem!)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  The "Aha!" Moment: Finding the Pattern
&lt;/h3&gt;

&lt;p&gt;Before jumping into code, let's think about how we'd build this triangle by hand.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Row 0:&lt;/strong&gt; Always &lt;code&gt;[1]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Row 1:&lt;/strong&gt; Always &lt;code&gt;[1, 1]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Row 2:&lt;/strong&gt; We know it starts and ends with &lt;code&gt;1&lt;/code&gt;. The middle element? It's the sum of the elements above it from Row 1: &lt;code&gt;1&lt;/code&gt; (left) + &lt;code&gt;1&lt;/code&gt; (right) = &lt;code&gt;2&lt;/code&gt;. So, &lt;code&gt;[1, 2, 1]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Row 3:&lt;/strong&gt; Starts and ends with &lt;code&gt;1&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;  The first inner element: &lt;code&gt;1&lt;/code&gt; (from Row 2, index 0) + &lt;code&gt;2&lt;/code&gt; (from Row 2, index 1) = &lt;code&gt;3&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  The second inner element: &lt;code&gt;2&lt;/code&gt; (from Row 2, index 1) + &lt;code&gt;1&lt;/code&gt; (from Row 2, index 2) = &lt;code&gt;3&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  So, &lt;code&gt;[1, 3, 3, 1]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do you see the pattern now? Each new row depends &lt;em&gt;entirely&lt;/em&gt; on the row immediately above it. This dependency is our key! We can generate the triangle row by row, using the previously generated row to construct the current one. This is a classic example of &lt;strong&gt;Dynamic Programming&lt;/strong&gt;, where we solve subproblems (generating previous rows) to solve the main problem (generating the whole triangle).&lt;/p&gt;




&lt;h3&gt;
  
  
  The Approach: Building It Up
&lt;/h3&gt;

&lt;p&gt;Here's our step-by-step strategy:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Initialize an empty list of lists (or vector of vectors in C++)&lt;/strong&gt; called &lt;code&gt;ans&lt;/code&gt;. This will hold our final Pascal's Triangle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Iterate &lt;code&gt;numRows&lt;/code&gt; times.&lt;/strong&gt; Let's say our loop variable &lt;code&gt;i&lt;/code&gt; represents the current row number we're trying to build (from 0 up to &lt;code&gt;numRows - 1&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;For each row &lt;code&gt;i&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Create a &lt;code&gt;temp&lt;/code&gt; list (or vector) to store the elements of the current row.&lt;/li&gt;
&lt;li&gt;  The current row &lt;code&gt;i&lt;/code&gt; will always have &lt;code&gt;i + 1&lt;/code&gt; elements.&lt;/li&gt;
&lt;li&gt;  Initialize &lt;code&gt;temp&lt;/code&gt; with &lt;code&gt;i + 1&lt;/code&gt; elements, setting all of them to &lt;code&gt;1&lt;/code&gt;. This conveniently handles the fact that the first and last elements of every row are always &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Calculate the inner elements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If &lt;code&gt;i&lt;/code&gt; is 0 or 1, the &lt;code&gt;temp&lt;/code&gt; row is already correct (&lt;code&gt;[1]&lt;/code&gt; or &lt;code&gt;[1, 1]&lt;/code&gt;). We don't need to do anything else.&lt;/li&gt;
&lt;li&gt;  If &lt;code&gt;i&lt;/code&gt; is greater than 1, we need to calculate the middle elements.&lt;/li&gt;
&lt;li&gt;  Loop &lt;code&gt;j&lt;/code&gt; from &lt;code&gt;1&lt;/code&gt; up to &lt;code&gt;i - 1&lt;/code&gt; (these are the indices of the inner elements).&lt;/li&gt;
&lt;li&gt;  For each &lt;code&gt;temp[j]&lt;/code&gt;, its value will be the sum of the element at &lt;code&gt;ans[i-1][j-1]&lt;/code&gt; and &lt;code&gt;ans[i-1][j]&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;ans[i-1]&lt;/code&gt; refers to the &lt;em&gt;previous&lt;/em&gt; row that we've already generated and stored.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;j-1&lt;/code&gt; and &lt;code&gt;j&lt;/code&gt; are the two elements directly above the current position &lt;code&gt;j&lt;/code&gt; in the &lt;em&gt;previous&lt;/em&gt; row.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add the &lt;code&gt;temp&lt;/code&gt; row to &lt;code&gt;ans&lt;/code&gt;.&lt;/strong&gt; After &lt;code&gt;temp&lt;/code&gt; is fully constructed for the current row &lt;code&gt;i&lt;/code&gt;, add it to our main &lt;code&gt;ans&lt;/code&gt; list.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Return &lt;code&gt;ans&lt;/code&gt;.&lt;/strong&gt; After the loop finishes, &lt;code&gt;ans&lt;/code&gt; will contain the complete Pascal's Triangle.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  The Code: Bringing It to Life (C++)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&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="nl"&gt;public:&lt;/span&gt;
    &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;numRows&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ans&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// This will store our complete Pascal's Triangle&lt;/span&gt;

        &lt;span class="c1"&gt;// Loop to generate each row, from row 0 up to numRows-1&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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;0&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;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;numRows&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="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Create a new vector for the current row.&lt;/span&gt;
            &lt;span class="c1"&gt;// It will have (i + 1) elements.&lt;/span&gt;
            &lt;span class="c1"&gt;// We initialize all elements to 1, which covers the first and last elements.&lt;/span&gt;
            &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;temp&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// If it's not the first or second row (rows 0 and 1 are just 1s)&lt;/span&gt;
            &lt;span class="c1"&gt;// we need to calculate the inner elements based on the previous row.&lt;/span&gt;
            &lt;span class="k"&gt;if&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;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Iterate from the second element (index 1) up to the second-to-last element (index i-1).&lt;/span&gt;
                &lt;span class="c1"&gt;// The first and last elements are already set to 1.&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;j&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="c1"&gt;// Each inner element is the sum of the two elements directly above it&lt;/span&gt;
                    &lt;span class="c1"&gt;// from the *previous* row (ans[i-1]).&lt;/span&gt;
                    &lt;span class="n"&gt;temp&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ans&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="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="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;ans&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="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="c1"&gt;// Add the newly constructed row to our overall triangle&lt;/span&gt;
            &lt;span class="n"&gt;ans&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// Return the final Pascal's Triangle&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ans&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Complexity Analysis
&lt;/h3&gt;

&lt;p&gt;Understanding how efficient our solution is crucial in competitive programming!&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;  We have an outer loop that runs &lt;code&gt;numRows&lt;/code&gt; times (once for each row).&lt;/li&gt;
&lt;li&gt;  Inside this loop, we have an inner loop that runs &lt;code&gt;i&lt;/code&gt; times (where &lt;code&gt;i&lt;/code&gt; is the current row number). The maximum value of &lt;code&gt;i&lt;/code&gt; is &lt;code&gt;numRows - 1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  So, in the worst case, we are doing operations proportional to &lt;code&gt;1 + 2 + ... + numRows&lt;/code&gt;. This sum is approximately &lt;code&gt;(numRows * (numRows + 1)) / 2&lt;/code&gt;, which simplifies to &lt;code&gt;O(numRows^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(numRows^2)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We are storing the entire Pascal's Triangle.&lt;/li&gt;
&lt;li&gt;  The total number of elements in a triangle with &lt;code&gt;numRows&lt;/code&gt; rows is also &lt;code&gt;1 + 2 + ... + numRows&lt;/code&gt;, which is &lt;code&gt;O(numRows^2)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Since the problem asks us to return the entire triangle, this space is necessary to store the output.&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;Pattern Recognition is King:&lt;/strong&gt; Many algorithmic problems can be simplified by identifying repeating patterns or relationships between elements.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Build It Incrementally:&lt;/strong&gt; For problems involving sequences or structures like triangles, often the best approach is to build the solution piece by piece, using previously computed results. This is the essence of dynamic programming!&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Arrays and Nested Loops:&lt;/strong&gt; This problem perfectly demonstrates how to use nested data structures (like &lt;code&gt;vector&amp;lt;vector&amp;lt;int&amp;gt;&amp;gt;&lt;/code&gt; in C++) and nested loops to generate complex structures.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Edge Cases:&lt;/strong&gt; Handling the first few rows (Row 0 and Row 1) where the "sum of two numbers above" rule doesn't fully apply is important. Our initialization of &lt;code&gt;temp&lt;/code&gt; with all &lt;code&gt;1&lt;/code&gt;s gracefully handles this!&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Congratulations on tackling Pascal's Triangle! This problem is a fantastic stepping stone into more complex dynamic programming challenges. Keep practicing, and you'll be solving even tougher problems in no time!&lt;/p&gt;

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




&lt;p&gt;&lt;em&gt;Authored by Vansh2710 | Published: 2026-04-07 23:59:07&lt;/em&gt;&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 876. Middle of the Linked List</title>
      <dc:creator>Vansh Aggarwal</dc:creator>
      <pubDate>Mon, 06 Apr 2026 18:03:52 +0000</pubDate>
      <link>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-876-middle-of-the-linked-list-ijg</link>
      <guid>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-876-middle-of-the-linked-list-ijg</guid>
      <description>&lt;h1&gt;
  
  
  Race to the Middle! Unlocking LeetCode 876: Middle of the Linked List
&lt;/h1&gt;

&lt;p&gt;Hey LeetCoders and aspiring developers! 👋 Vansh2710 here, ready to dive into another fun LeetCode challenge that's perfect for strengthening your understanding of linked lists. Today, we're tackling &lt;strong&gt;Problem 876: Middle of the Linked List&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This problem is a fantastic introduction to a super common and powerful technique for linked list manipulation. So, grab your favorite beverage, and let's unravel this together!&lt;/p&gt;




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

&lt;p&gt;Imagine you have a chain of connected boxes (that's a linked list!). Each box contains a number and a pointer (an arrow) to the next box in the chain. The &lt;em&gt;head&lt;/em&gt; is the very first box.&lt;/p&gt;

&lt;p&gt;Our mission is simple: find the box that's right in the middle of this chain.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;If the chain has an odd number of boxes:&lt;/strong&gt; There's clearly one middle box. We need to return that box and all the boxes that come after it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Example 1:&lt;/strong&gt; &lt;code&gt;head = [1, 2, 3, 4, 5]&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;  The middle box is &lt;code&gt;3&lt;/code&gt;. We return &lt;code&gt;[3, 4, 5]&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;If the chain has an even number of boxes:&lt;/strong&gt; There are two "middle" boxes. The problem specifically asks us to return the &lt;em&gt;second&lt;/em&gt; of these two middle boxes, and all boxes after it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Example 2:&lt;/strong&gt; &lt;code&gt;head = [1, 2, 3, 4, 5, 6]&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;  The two middle boxes are &lt;code&gt;3&lt;/code&gt; and &lt;code&gt;4&lt;/code&gt;. We need to return &lt;code&gt;4&lt;/code&gt; (the second one) and everything after it: &lt;code&gt;[4, 5, 6]&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;The constraints are pretty forgiving: the list will have between 1 and 100 nodes. This means we don't have to worry about super long lists for now, but our solution should ideally be efficient!&lt;/p&gt;




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

&lt;p&gt;How would you find the middle of a chain if you could only look at one box at a time and move forward?&lt;/p&gt;

&lt;p&gt;A simple way might be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Count all the boxes in the chain. Let's say there are &lt;code&gt;N&lt;/code&gt; boxes.&lt;/li&gt;
&lt;li&gt; Calculate the middle index. If &lt;code&gt;N&lt;/code&gt; is 5, the middle is &lt;code&gt;(5 / 2) + 1 = 3&lt;/code&gt; (1-indexed). If &lt;code&gt;N&lt;/code&gt; is 6, the middle is &lt;code&gt;(6 / 2) + 1 = 4&lt;/code&gt; (1-indexed, for the second middle).&lt;/li&gt;
&lt;li&gt; Then, start from the beginning again and move &lt;code&gt;(middle_index - 1)&lt;/code&gt; steps forward to reach the middle box.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This works, but it requires &lt;em&gt;two passes&lt;/em&gt; through our linked list: one to count, and one to find the node. Can we do better? Can we find the middle in just &lt;em&gt;one pass&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Think about two runners on a race track...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine you have two runners starting at the same point.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  One runner (&lt;code&gt;slow&lt;/code&gt;) takes one step at a time.&lt;/li&gt;
&lt;li&gt;  The other runner (&lt;code&gt;fast&lt;/code&gt;) takes two steps at a time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If they both start from the beginning of the linked list, by the time the &lt;code&gt;fast&lt;/code&gt; runner reaches the end of the list, where will the &lt;code&gt;slow&lt;/code&gt; runner be?&lt;/p&gt;

&lt;p&gt;Precisely! The &lt;code&gt;slow&lt;/code&gt; runner will be exactly at the middle! Because the &lt;code&gt;fast&lt;/code&gt; runner covers twice the distance in the same amount of time, when &lt;code&gt;fast&lt;/code&gt; has reached the finish line, &lt;code&gt;slow&lt;/code&gt; has only covered half the track. This is the &lt;strong&gt;Two Pointers (or Fast &amp;amp; Slow Pointers) technique&lt;/strong&gt;!&lt;/p&gt;




&lt;h2&gt;
  
  
  🪜 Approach: Stepping Through the Solution
&lt;/h2&gt;

&lt;p&gt;Let's formalize our two-pointer strategy:&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;slow&lt;/code&gt; pointer, starting at &lt;code&gt;head&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;fast&lt;/code&gt; pointer, also starting at &lt;code&gt;head&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Traverse the list with both pointers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  In each step of our loop:

&lt;ul&gt;
&lt;li&gt;  Move &lt;code&gt;slow&lt;/code&gt; one step forward: &lt;code&gt;slow = slow-&amp;gt;next;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Move &lt;code&gt;fast&lt;/code&gt; two steps forward: &lt;code&gt;fast = fast-&amp;gt;next-&amp;gt;next;&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;Determine the loop's stopping condition:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The &lt;code&gt;fast&lt;/code&gt; pointer is leading the race. It will reach the end first.&lt;/li&gt;
&lt;li&gt;  We need to stop when &lt;code&gt;fast&lt;/code&gt; or &lt;code&gt;fast-&amp;gt;next&lt;/code&gt; becomes &lt;code&gt;nullptr&lt;/code&gt; (meaning &lt;code&gt;fast&lt;/code&gt; has reached or gone past the end of the list).&lt;/li&gt;
&lt;li&gt;  So, our loop continues &lt;code&gt;while (fast != nullptr &amp;amp;&amp;amp; fast-&amp;gt;next != nullptr)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Why this works for both odd and even lists:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Odd length list (e.g., &lt;code&gt;[1, 2, 3, 4, 5]&lt;/code&gt;):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  Start: &lt;code&gt;slow&lt;/code&gt;=1, &lt;code&gt;fast&lt;/code&gt;=1&lt;/li&gt;
&lt;li&gt;  Step 1: &lt;code&gt;slow&lt;/code&gt;=2, &lt;code&gt;fast&lt;/code&gt;=3&lt;/li&gt;
&lt;li&gt;  Step 2: &lt;code&gt;slow&lt;/code&gt;=3, &lt;code&gt;fast&lt;/code&gt;=5&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;fast-&amp;gt;next&lt;/code&gt; is &lt;code&gt;nullptr&lt;/code&gt; (after 5). The loop terminates. &lt;code&gt;slow&lt;/code&gt; is at &lt;code&gt;3&lt;/code&gt;, which is our desired middle node.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Even length list (e.g., &lt;code&gt;[1, 2, 3, 4, 5, 6]&lt;/code&gt;):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  Start: &lt;code&gt;slow&lt;/code&gt;=1, &lt;code&gt;fast&lt;/code&gt;=1&lt;/li&gt;
&lt;li&gt;  Step 1: &lt;code&gt;slow&lt;/code&gt;=2, &lt;code&gt;fast&lt;/code&gt;=3&lt;/li&gt;
&lt;li&gt;  Step 2: &lt;code&gt;slow&lt;/code&gt;=3, &lt;code&gt;fast&lt;/code&gt;=5&lt;/li&gt;
&lt;li&gt;  Step 3: &lt;code&gt;slow&lt;/code&gt;=4, &lt;code&gt;fast&lt;/code&gt; points to &lt;code&gt;nullptr&lt;/code&gt; (after 6, so &lt;code&gt;fast&lt;/code&gt; is &lt;code&gt;nullptr&lt;/code&gt; in the next iteration if &lt;code&gt;fast-&amp;gt;next&lt;/code&gt; was checked first, or &lt;code&gt;fast-&amp;gt;next&lt;/code&gt; is &lt;code&gt;nullptr&lt;/code&gt; if &lt;code&gt;fast&lt;/code&gt; is &lt;code&gt;6&lt;/code&gt; but &lt;code&gt;fast-&amp;gt;next&lt;/code&gt; is &lt;code&gt;nullptr&lt;/code&gt;). The loop terminates. &lt;code&gt;slow&lt;/code&gt; is at &lt;code&gt;4&lt;/code&gt;, which is the second middle node, as required!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Return &lt;code&gt;slow&lt;/code&gt;:&lt;/strong&gt; When the loop finishes, &lt;code&gt;slow&lt;/code&gt; will be pointing to the middle node (or the second middle node for even-length lists).&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This elegant solution finds the middle in a single pass!&lt;/p&gt;




&lt;h2&gt;
  
  
  💻 Code: Bringing it to Life
&lt;/h2&gt;

&lt;p&gt;Here's the C++ implementation using the fast and slow pointer technique:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(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="nl"&gt;public:&lt;/span&gt;
    &lt;span class="n"&gt;ListNode&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;middleNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ListNode&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ListNode&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;slow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;ListNode&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;fast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Loop until fast reaches the end of the list (or one node before the end)&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fast&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;fast&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;slow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;slow&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// slow moves one step&lt;/span&gt;
            &lt;span class="n"&gt;fast&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fast&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;next&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// fast moves two steps&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// When fast reaches the end, slow will be at the middle&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;slow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;Let &lt;code&gt;N&lt;/code&gt; be the number of nodes in the linked list.&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;  We traverse the linked list exactly once. The &lt;code&gt;fast&lt;/code&gt; pointer covers &lt;code&gt;N&lt;/code&gt; nodes (or slightly less/more depending on N's parity), and the &lt;code&gt;slow&lt;/code&gt; pointer covers &lt;code&gt;N/2&lt;/code&gt; nodes. Regardless, the number of operations scales linearly with the number of nodes.&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 only use a constant amount of extra space for our &lt;code&gt;slow&lt;/code&gt; and &lt;code&gt;fast&lt;/code&gt; pointers, regardless of the list's size. No auxiliary data structures are used.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This is an optimal solution in terms of both time and space complexity!&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Two Pointers (Fast &amp;amp; Slow Pointers):&lt;/strong&gt; This is a cornerstone technique for linked list problems! It's incredibly useful for finding the middle, detecting cycles, or finding the &lt;code&gt;k&lt;/code&gt;-th node from the end.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Single Pass Efficiency:&lt;/strong&gt; By using two pointers moving at different speeds, we can often solve problems that might otherwise require multiple passes, saving computation time.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Edge Cases for Linked Lists:&lt;/strong&gt; Always consider empty lists, single-node lists, and two-node lists when designing your logic. Here, &lt;code&gt;fast != nullptr &amp;amp;&amp;amp; fast-&amp;gt;next != nullptr&lt;/code&gt; elegantly handles these.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;That's a wrap for Problem 876! I hope this deep dive into the "Middle of the Linked List" problem has demystified the fast and slow pointer technique for you. Keep practicing, and you'll master these patterns in no time!&lt;/p&gt;

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




&lt;p&gt;&lt;em&gt;Authored by Vansh2710&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Published: 2026-04-06 23:32:58&lt;/em&gt;&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 450. Delete Node in a BST</title>
      <dc:creator>Vansh Aggarwal</dc:creator>
      <pubDate>Sun, 05 Apr 2026 16:37:03 +0000</pubDate>
      <link>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-450-delete-node-in-a-bst-4ad1</link>
      <guid>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-450-delete-node-in-a-bst-4ad1</guid>
      <description>&lt;h1&gt;
  
  
  Conquering BST Deletion: A Beginner's Guide to LeetCode 450
&lt;/h1&gt;

&lt;p&gt;Hey amazing developers! Vansh2710 here, ready to tackle another classic LeetCode problem. Today, we're diving into the sometimes-tricky world of &lt;strong&gt;Binary Search Tree (BST) deletion&lt;/strong&gt;. Specifically, we're taking on &lt;a href="https://leetcode.com/problems/delete-node-in-a-bst/" rel="noopener noreferrer"&gt;LeetCode 450: Delete Node in a BST&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Don't let the "deletion" part scare you! While it might seem intimidating at first, we'll break it down step-by-step, making it super clear and manageable. Think of it as a puzzle with a few distinct pieces – once you understand each piece, the whole picture becomes simple.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem Explained: Deleting a Node from a BST
&lt;/h2&gt;

&lt;p&gt;Imagine you have a phone directory (a BST!). Each entry (node) has a name (value). You want to remove an old contact (a key) from this directory while making sure it remains sorted alphabetically (maintaining the BST property).&lt;/p&gt;

&lt;p&gt;That's essentially what LeetCode 450 asks us to do:&lt;br&gt;
Given the &lt;code&gt;root&lt;/code&gt; of a Binary Search Tree and a &lt;code&gt;key&lt;/code&gt; (the value of the node you want to delete):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Search&lt;/strong&gt;: First, locate the node that contains the &lt;code&gt;key&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Delete&lt;/strong&gt;: If the node is found, remove it. The tricky part is ensuring that after deletion, the tree remains a valid BST! If the node isn't found, simply return the original tree.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What is a BST, again?&lt;/strong&gt;&lt;br&gt;
A Binary Search Tree is a special type of binary tree where for every node:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  All values in its &lt;strong&gt;left subtree&lt;/strong&gt; are &lt;strong&gt;less than&lt;/strong&gt; the node's value.&lt;/li&gt;
&lt;li&gt;  All values in its &lt;strong&gt;right subtree&lt;/strong&gt; are &lt;strong&gt;greater than&lt;/strong&gt; the node's value.
This property makes searching, insertion, and deletion very efficient!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's look at an example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1:&lt;/strong&gt;&lt;br&gt;
Input: &lt;code&gt;root = [5,3,6,2,4,null,7], key = 3&lt;/code&gt;&lt;br&gt;
Output: &lt;code&gt;[5,4,6,2,null,null,7]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Initially:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    5
   / \
  3   6
 / \   \
2   4   7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We want to delete &lt;code&gt;3&lt;/code&gt;. Notice how &lt;code&gt;4&lt;/code&gt; takes its place to maintain the BST property ( &lt;code&gt;4&lt;/code&gt; is greater than &lt;code&gt;2&lt;/code&gt; and less than &lt;code&gt;5&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;After deleting &lt;code&gt;3&lt;/code&gt; and replacing with &lt;code&gt;4&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    5
   / \
  4   6
 /     \
2       7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Another valid answer could have &lt;code&gt;2&lt;/code&gt; taking &lt;code&gt;3&lt;/code&gt;'s place!)&lt;/p&gt;

&lt;p&gt;The key takeaway here is that when you remove a node, you need to find a suitable replacement that keeps the whole tree "sorted."&lt;/p&gt;




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

&lt;p&gt;The core idea behind BST deletion is maintaining its fundamental property. When you remove a node, its children (if any) can't just float in space. They need to be reattached in a way that preserves the BST order.&lt;/p&gt;

&lt;p&gt;The "aha!" moment comes from realizing there are three main scenarios when you find the node to delete:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;It's a leaf node (no children):&lt;/strong&gt; This is the easiest! Just remove it. No children to worry about.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;It has one child:&lt;/strong&gt; The child can simply take the place of the deleted node. If you delete node &lt;code&gt;X&lt;/code&gt; which has only a left child &lt;code&gt;L&lt;/code&gt;, then &lt;code&gt;L&lt;/code&gt; becomes the new child of &lt;code&gt;X&lt;/code&gt;'s parent. The BST property holds because all nodes in &lt;code&gt;L&lt;/code&gt;'s subtree are still less than &lt;code&gt;X&lt;/code&gt;'s parent (if &lt;code&gt;X&lt;/code&gt; was a left child) or greater (if &lt;code&gt;X&lt;/code&gt; was a right child).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;It has two children:&lt;/strong&gt; This is the trickiest part! You can't just pick one child, as the other would be lost. Here's where we get clever:

&lt;ul&gt;
&lt;li&gt;  To maintain the BST property, the replacement node must be greater than all nodes in the left subtree and less than all nodes in the right subtree.&lt;/li&gt;
&lt;li&gt;  The perfect candidates for this are either the &lt;strong&gt;smallest node in the right subtree&lt;/strong&gt; (also known as the in-order successor) or the &lt;strong&gt;largest node in the left subtree&lt;/strong&gt; (the in-order predecessor).&lt;/li&gt;
&lt;li&gt;  If we replace the deleted node's value with its in-order successor's value, the BST property is preserved. Then, we simply delete that successor from its &lt;em&gt;original&lt;/em&gt; position in the right subtree (which will be one of the easier cases: a leaf or a node with one child, specifically a right child).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We can use a &lt;strong&gt;recursive approach&lt;/strong&gt; for this. Why? Because searching for the node and then potentially deleting a replacement node (if it has two children) are both operations that can be naturally handled by recursion, similar to how we traverse BSTs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Approach: Step-by-Step Logic
&lt;/h2&gt;

&lt;p&gt;Let's translate that intuition into a concrete algorithm:&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;deleteNode(root, key)&lt;/code&gt; function will work recursively:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Base Case:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If &lt;code&gt;root&lt;/code&gt; is &lt;code&gt;nullptr&lt;/code&gt; (the tree is empty or we've searched past a leaf), the &lt;code&gt;key&lt;/code&gt; isn't found. Return &lt;code&gt;nullptr&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Search Phase:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If &lt;code&gt;key &amp;lt; root-&amp;gt;val&lt;/code&gt;: The node we want to delete must be in the left subtree. Recursively call &lt;code&gt;root-&amp;gt;left = deleteNode(root-&amp;gt;left, key)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  If &lt;code&gt;key &amp;gt; root-&amp;gt;val&lt;/code&gt;: The node we want to delete must be in the right subtree. Recursively call &lt;code&gt;root-&amp;gt;right = deleteNode(root-&amp;gt;right, key)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deletion Phase (when &lt;code&gt;key == root-&amp;gt;val&lt;/code&gt;):&lt;/strong&gt; We found the node to delete! Now, we handle the three cases:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*   **Case 1: Node has no children (Leaf Node)**
    *   Simply delete the `root` node and return `nullptr` to its parent, effectively removing it from the tree.

*   **Case 2: Node has one child**
    *   If `root-&amp;gt;left` is `nullptr` (only a right child): Store `root-&amp;gt;right` in a temporary variable, delete `root`, and return the `temp` node. The right child takes its parent's place.
    *   If `root-&amp;gt;right` is `nullptr` (only a left child): Store `root-&amp;gt;left` in a temporary variable, delete `root`, and return the `temp` node. The left child takes its parent's place.

*   **Case 3: Node has two children**
    *   This is the most involved part. We need to find the in-order successor.
    *   **Find Successor:** Traverse to the right child of the current `root`, then keep going left as far as possible. This will give you the smallest node in the right subtree. Let's call this `successor`.
    *   **Replace Value:** Copy `successor-&amp;gt;val` into `root-&amp;gt;val`. Now, the current node `root` has the value of its successor.
    *   **Delete Successor:** The `successor` node is now duplicated. We need to remove its original position. Recursively call `root-&amp;gt;right = deleteNode(root-&amp;gt;right, successor-&amp;gt;val)`. This will remove the `successor` from the right subtree, which will be an easier deletion case (either a leaf or a node with one right child).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Return &lt;code&gt;root&lt;/code&gt;:&lt;/strong&gt; After any modifications (or if no deletion happened), always return the current &lt;code&gt;root&lt;/code&gt; back to its parent. This is crucial for correctly rebuilding the tree structure in the recursive calls.&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;Here's the C++ implementation following our approach.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */&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="nl"&gt;public:&lt;/span&gt;
    &lt;span class="n"&gt;TreeNode&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;deleteNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TreeNode&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Base Case: If the tree is empty or key not found&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Search Phase: Traverse the BST to find the node&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="c1"&gt;// Key is smaller, go to the left subtree&lt;/span&gt;
            &lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;deleteNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&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;key&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
            &lt;span class="c1"&gt;// Key is larger, go to the right subtree&lt;/span&gt;
            &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;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;deleteNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;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;key&lt;/span&gt;&lt;span class="p"&gt;);&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="c1"&gt;// key == root-&amp;gt;val: Node to be deleted found!&lt;/span&gt;
            &lt;span class="c1"&gt;// Case 1: Node has no children (it's a leaf)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Free memory&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// This node is now gone&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="c1"&gt;// Case 2: Node has only one child&lt;/span&gt;
            &lt;span class="k"&gt;else&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;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="c1"&gt;// Only right child exists&lt;/span&gt;
                &lt;span class="n"&gt;TreeNode&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;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;// Store the right child&lt;/span&gt;
                &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Delete the current node&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Replace current node with its right child&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;else&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;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; &lt;span class="c1"&gt;// Only left child exists&lt;/span&gt;
                &lt;span class="n"&gt;TreeNode&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;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;// Store the left child&lt;/span&gt;
                &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Delete the current node&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Replace current node with its left child&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="c1"&gt;// Case 3: Node has two children&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;// Find the in-order successor (smallest node in the right subtree)&lt;/span&gt;
                &lt;span class="n"&gt;TreeNode&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;successor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;successor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                    &lt;span class="n"&gt;successor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;successor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="c1"&gt;// Replace the value of the current node with the successor's value&lt;/span&gt;
                &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;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;successor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="c1"&gt;// Recursively delete the successor from the right subtree&lt;/span&gt;
                &lt;span class="c1"&gt;// The successor will either be a leaf or have only a right child,&lt;/span&gt;
                &lt;span class="c1"&gt;// making its deletion simple.&lt;/span&gt;
                &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;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;deleteNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;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;successor&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// Return the (potentially updated) root of the current subtree&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&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;Let's break down how efficient our solution is:&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;H&lt;/code&gt; is the height of the BST.&lt;/li&gt;
&lt;li&gt;  In the worst case (a skewed tree, like a linked list), &lt;code&gt;H&lt;/code&gt; can be &lt;code&gt;N&lt;/code&gt; (number of nodes). In the best case (a balanced tree), &lt;code&gt;H&lt;/code&gt; is &lt;code&gt;log N&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Why O(H)?

&lt;ul&gt;
&lt;li&gt;  The search phase involves traversing down the tree, at most &lt;code&gt;H&lt;/code&gt; levels.&lt;/li&gt;
&lt;li&gt;  If the node has two children, finding the successor also involves traversing down the right subtree, at most &lt;code&gt;H&lt;/code&gt; levels.&lt;/li&gt;
&lt;li&gt;  The recursive call to delete the successor also follows a path down the tree, again at most &lt;code&gt;H&lt;/code&gt; levels.&lt;/li&gt;
&lt;li&gt;  All these operations combined are proportional to the height of the tree.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

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

&lt;ul&gt;
&lt;li&gt;  This is due to the recursion call stack. In the worst case, if the tree is highly skewed, the recursion depth can be &lt;code&gt;N&lt;/code&gt;. For a balanced tree, it's &lt;code&gt;log N&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This solution perfectly meets the follow-up requirement of solving it with time complexity O(height of tree)!&lt;/p&gt;




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

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Recursive Thinking is Your Friend&lt;/strong&gt;: BST problems often lend themselves beautifully to recursion. Thinking about how to solve a subproblem and combine results is key.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Three Deletion Cases&lt;/strong&gt;: The heart of BST deletion lies in distinguishing and handling leaf nodes, nodes with one child, and nodes with two children separately.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;In-order Successor/Predecessor&lt;/strong&gt;: For nodes with two children, the in-order successor (smallest in right subtree) or predecessor (largest in left subtree) is your go-to replacement to maintain the BST property.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Memory Management&lt;/strong&gt;: In C++, remember to &lt;code&gt;delete&lt;/code&gt; nodes to prevent memory leaks, especially when you are freeing up a node's memory.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;BST deletion is a foundational concept in data structures. Mastering it gives you a deeper understanding of how trees work and how to manipulate them efficiently. Keep practicing, and you'll be a BST pro in no time!&lt;/p&gt;

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




&lt;p&gt;&lt;strong&gt;Author Account:&lt;/strong&gt; Vansh2710&lt;br&gt;
&lt;strong&gt;Time Published:&lt;/strong&gt; 2026-04-05 22:06:35&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 938. Range Sum of BST</title>
      <dc:creator>Vansh Aggarwal</dc:creator>
      <pubDate>Sat, 04 Apr 2026 17:15:21 +0000</pubDate>
      <link>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-938-range-sum-of-bst-1e8i</link>
      <guid>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-938-range-sum-of-bst-1e8i</guid>
      <description>&lt;h1&gt;
  
  
  Unleash Your Inner Tree Wizard: Summing Values in a BST Range (LeetCode #938)
&lt;/h1&gt;

&lt;p&gt;Hey fellow coders! 👋 Vansh2710 here, diving deep into another LeetCode adventure. Today, we're tackling a super common and insightful problem that truly highlights the power of Binary Search Trees (BSTs): &lt;strong&gt;Problem 938: Range Sum of BST&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This problem is a fantastic way to solidify your understanding of tree traversals and how to leverage the unique properties of a BST for efficiency. Let's get cracking!&lt;/p&gt;

&lt;h2&gt;
  
  
  🌳 Problem Explanation: What's the Goal?
&lt;/h2&gt;

&lt;p&gt;Imagine you have a special kind of tree called a &lt;strong&gt;Binary Search Tree (BST)&lt;/strong&gt;. What makes it special? For every node in the tree:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; All values in its &lt;strong&gt;left subtree&lt;/strong&gt; are &lt;strong&gt;smaller&lt;/strong&gt; than the node's own value.&lt;/li&gt;
&lt;li&gt; All values in its &lt;strong&gt;right subtree&lt;/strong&gt; are &lt;strong&gt;larger&lt;/strong&gt; than the node's own value.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Pretty neat, right? This property is what makes BSTs so powerful for searching and sorting.&lt;/p&gt;

&lt;p&gt;Now, for this problem, you're given:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The &lt;code&gt;root&lt;/code&gt; node of one of these amazing BSTs.&lt;/li&gt;
&lt;li&gt;  Two integers, &lt;code&gt;low&lt;/code&gt; and &lt;code&gt;high&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your mission, should you choose to accept it (which you will!): &lt;strong&gt;Find the sum of all node values that fall within the inclusive range &lt;code&gt;[low, high]&lt;/code&gt;&lt;/strong&gt;. This means any node with a value &lt;code&gt;val&lt;/code&gt; where &lt;code&gt;low &amp;lt;= val &amp;lt;= high&lt;/code&gt; should be added to our total.&lt;/p&gt;

&lt;p&gt;Let's look at an example to make it crystal clear:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1:&lt;/strong&gt;&lt;br&gt;
Input: &lt;code&gt;root = [10,5,15,3,7,null,18]&lt;/code&gt;, &lt;code&gt;low = 7&lt;/code&gt;, &lt;code&gt;high = 15&lt;/code&gt;&lt;br&gt;
Output: &lt;code&gt;32&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Here's how that tree looks and why the answer is 32:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        10
       /  \
      5    15
     / \    \
    3   7    18
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nodes in range &lt;code&gt;[7, 15]&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;7&lt;/code&gt; (Yes, 7 is &amp;gt;= 7 and &amp;lt;= 15)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;10&lt;/code&gt; (Yes, 10 is &amp;gt;= 7 and &amp;lt;= 15)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;15&lt;/code&gt; (Yes, 15 is &amp;gt;= 7 and &amp;lt;= 15)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The sum is &lt;code&gt;7 + 10 + 15 = 32&lt;/code&gt;. Nodes like &lt;code&gt;3&lt;/code&gt;, &lt;code&gt;5&lt;/code&gt;, and &lt;code&gt;18&lt;/code&gt; are outside the range, so we ignore them.&lt;/p&gt;

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

&lt;p&gt;At first glance, you might think, "Okay, I'll just traverse the entire tree (like a depth-first search or breadth-first search), check each node, and if it's in the range, add it to my sum." And you know what? That approach &lt;em&gt;would&lt;/em&gt; work! It's perfectly valid.&lt;/p&gt;

&lt;p&gt;But wait, we have a &lt;strong&gt;Binary Search Tree&lt;/strong&gt;! Can we do better? The BST property is our secret weapon here. It tells us a lot about which parts of the tree are worth exploring and which are definitely not.&lt;/p&gt;

&lt;p&gt;Here's the "aha!":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If our current node's value (&lt;code&gt;root-&amp;gt;val&lt;/code&gt;) is &lt;strong&gt;smaller than &lt;code&gt;low&lt;/code&gt;&lt;/strong&gt;, we know for sure that its entire &lt;strong&gt;left subtree&lt;/strong&gt; contains values even &lt;em&gt;smaller&lt;/em&gt; than &lt;code&gt;root-&amp;gt;val&lt;/code&gt;. So, none of them can possibly be in our &lt;code&gt;[low, high]&lt;/code&gt; range. We can completely skip the left subtree and only look at the &lt;strong&gt;right subtree&lt;/strong&gt;!&lt;/li&gt;
&lt;li&gt;  Similarly, if &lt;code&gt;root-&amp;gt;val&lt;/code&gt; is &lt;strong&gt;larger than &lt;code&gt;high&lt;/code&gt;&lt;/strong&gt;, we know its entire &lt;strong&gt;right subtree&lt;/strong&gt; contains values even &lt;em&gt;larger&lt;/em&gt; than &lt;code&gt;root-&amp;gt;val&lt;/code&gt;. None of &lt;em&gt;those&lt;/em&gt; can be in our range. We can skip the right subtree and only look at the &lt;strong&gt;left subtree&lt;/strong&gt;!&lt;/li&gt;
&lt;li&gt;  If &lt;code&gt;root-&amp;gt;val&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; within our &lt;code&gt;[low, high]&lt;/code&gt; range, then we add it to our sum, AND we need to explore &lt;strong&gt;both&lt;/strong&gt; its left and right subtrees, because they &lt;em&gt;might&lt;/em&gt; contain other nodes within the range.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This insight allows us to "prune" (cut off) entire branches of the tree that we know won't contain any relevant nodes, making our solution much more efficient!&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Approach: A Recursive Journey
&lt;/h2&gt;

&lt;p&gt;We'll use a recursive Depth-First Search (DFS) approach to traverse the tree, smartly skipping subtrees based on the BST property.&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;Base Case:&lt;/strong&gt; If we encounter a &lt;code&gt;null&lt;/code&gt; node (meaning we've gone past a leaf or an empty branch), there's nothing to add. We simply return &lt;code&gt;0&lt;/code&gt;. This stops our recursion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Check Current Node's Value:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;If &lt;code&gt;root-&amp;gt;val&lt;/code&gt; is between &lt;code&gt;low&lt;/code&gt; and &lt;code&gt;high&lt;/code&gt; (inclusive):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  This node's value is part of our sum! Add &lt;code&gt;root-&amp;gt;val&lt;/code&gt; to our total.&lt;/li&gt;
&lt;li&gt;  Since its children could also be in the range, we need to recursively call our function for both the &lt;code&gt;root-&amp;gt;left&lt;/code&gt; and &lt;code&gt;root-&amp;gt;right&lt;/code&gt; subtrees and add their returned sums.&lt;/li&gt;
&lt;li&gt;  So, &lt;code&gt;return root-&amp;gt;val + rangeSumBST(root-&amp;gt;left, low, high) + rangeSumBST(root-&amp;gt;right, low, high);&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;*   **If `root-&amp;gt;val` is less than `low`:**
    *   We know `root-&amp;gt;val` is too small.
    *   Because it's a BST, all values in its `root-&amp;gt;left` subtree will be even *smaller* than `root-&amp;gt;val`, so they definitely won't be in our `[low, high]` range. We can ignore the left subtree!
    *   However, values in the `root-&amp;gt;right` subtree *could* be larger than `low` and thus potentially in our range.
    *   So, we only need to recursively call for the `root-&amp;gt;right` subtree: `return rangeSumBST(root-&amp;gt;right, low, high);`

*   **If `root-&amp;gt;val` is greater than `high`:**
    *   We know `root-&amp;gt;val` is too large.
    *   Because it's a BST, all values in its `root-&amp;gt;right` subtree will be even *larger* than `root-&amp;gt;val`, so they definitely won't be in our `[low, high]` range. We can ignore the right subtree!
    *   However, values in the `root-&amp;gt;left` subtree *could* be smaller than `high` and thus potentially in our range.
    *   So, we only need to recursively call for the `root-&amp;gt;left` subtree: `return rangeSumBST(root-&amp;gt;left, low, high);`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;And that's it! This intelligent pruning makes our solution incredibly efficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧑‍💻 Code
&lt;/h2&gt;

&lt;p&gt;Here's the C++ implementation reflecting our approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */&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="nl"&gt;public:&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;rangeSumBST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TreeNode&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Base case: If the current node is null, there's nothing to add.&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;nullptr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Case 1: Current node's value is within the range [low, high]&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Add current node's value and recursively sum from both children.&lt;/span&gt;
            &lt;span class="c1"&gt;// Both left and right subtrees might contain nodes in the range.&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;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;rangeSumBST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;rangeSumBST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;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;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// Case 2: Current node's value is less than 'low'&lt;/span&gt;
        &lt;span class="k"&gt;else&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;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// All nodes in the left subtree will also be less than 'low' (BST property).&lt;/span&gt;
            &lt;span class="c1"&gt;// So, we only need to explore the right subtree.&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rangeSumBST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;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;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;// Case 3: Current node's value is greater than 'high'&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;// root-&amp;gt;val &amp;gt; high&lt;/span&gt;
            &lt;span class="c1"&gt;// All nodes in the right subtree will also be greater than 'high' (BST property).&lt;/span&gt;
            &lt;span class="c1"&gt;// So, we only need to explore the left subtree.&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;rangeSumBST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;low&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;high&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⏱️ Complexity Analysis
&lt;/h2&gt;

&lt;p&gt;Let's break down how efficient our solution is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Time Complexity: O(N)&lt;/strong&gt; in the worst case, but often much better.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  In the worst-case scenario (e.g., if &lt;code&gt;low&lt;/code&gt; is 1 and &lt;code&gt;high&lt;/code&gt; is 10^5, covering the entire tree's possible range), we might end up visiting every single node in the tree. If there are &lt;code&gt;N&lt;/code&gt; nodes, this would be O(N).&lt;/li&gt;
&lt;li&gt;  However, thanks to the BST property and our pruning strategy, we only visit nodes that &lt;em&gt;could&lt;/em&gt; potentially be within the &lt;code&gt;[low, high]&lt;/code&gt; range. This means we avoid traversing entire subtrees that we know are irrelevant. So, while the upper bound is O(N), for many inputs, it's significantly faster than a generic tree traversal.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

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

&lt;ul&gt;
&lt;li&gt;  This is due to the recursion call stack. &lt;code&gt;H&lt;/code&gt; represents the height of the binary search tree.&lt;/li&gt;
&lt;li&gt;  In the worst case (a skewed tree, resembling a linked list), the height &lt;code&gt;H&lt;/code&gt; could be &lt;code&gt;N&lt;/code&gt; (the number of nodes). So, space complexity would be O(N).&lt;/li&gt;
&lt;li&gt;  In the best/average case (a balanced tree), the height &lt;code&gt;H&lt;/code&gt; is &lt;code&gt;log N&lt;/code&gt;. So, space complexity would be O(log N).&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;BST Properties are Gold:&lt;/strong&gt; Always look for ways to leverage the unique characteristics of a data structure. For BSTs, the &lt;code&gt;left &amp;lt; root &amp;lt; right&lt;/code&gt; rule is incredibly powerful for optimizing searches and traversals.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Recursive Thinking for Trees:&lt;/strong&gt; Many tree problems lend themselves beautifully to recursive solutions. Define your base case and how to combine results from subproblems.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Pruning for Performance:&lt;/strong&gt; Smartly skipping irrelevant parts of the data structure (like entire subtrees here) can drastically improve the efficiency of your algorithms.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This problem is a fantastic stepping stone for understanding more complex BST problems and reinforcing your tree traversal skills. Keep practicing, and you'll be a tree wizard in no time! Happy coding! ✨&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Author Account: Vansh2710 | Time Published: 2026-04-04 22:44:40&lt;/em&gt;&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 869. Reordered Power of 2</title>
      <dc:creator>Vansh Aggarwal</dc:creator>
      <pubDate>Fri, 03 Apr 2026 18:54:31 +0000</pubDate>
      <link>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-869-reordered-power-of-2-4g5n</link>
      <guid>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-869-reordered-power-of-2-4g5n</guid>
      <description>&lt;h1&gt;
  
  
  Unraveling LeetCode 869: Can Your Number Shuffle into a Power of Two?
&lt;/h1&gt;

&lt;p&gt;Hey everyone! Vansh2710 here, ready to tackle another intriguing LeetCode challenge. Today, we're diving into problem 869, "Reordered Power of 2." This problem sounds like a fun riddle: given a number, can you rearrange its digits to form a power of two? Let's break it down!&lt;/p&gt;




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

&lt;p&gt;You're given an integer &lt;code&gt;n&lt;/code&gt;. Your task is to figure out if you can reorder its digits in any way to form a new number that is a power of two.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important Rules:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Reordering:&lt;/strong&gt; You can arrange the digits of &lt;code&gt;n&lt;/code&gt; in any order.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Leading Digit:&lt;/strong&gt; The new number you form &lt;em&gt;cannot&lt;/em&gt; have a leading zero (unless the number itself is just '0', which isn't a power of two we're interested in here).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Power of Two:&lt;/strong&gt; The resulting number must be a power of two (i.e., 1, 2, 4, 8, 16, 32, ... which are &lt;code&gt;2^0, 2^1, 2^2&lt;/code&gt;, and so on).&lt;/li&gt;
&lt;/ol&gt;

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

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

&lt;ul&gt;
&lt;li&gt;  The digits of &lt;code&gt;n&lt;/code&gt; are just &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Can we reorder &lt;code&gt;1&lt;/code&gt;? Well, it's already &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Is &lt;code&gt;1&lt;/code&gt; a power of two? Yes, &lt;code&gt;2^0 = 1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Output: &lt;code&gt;true&lt;/code&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Example 2: &lt;code&gt;n = 10&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The digits of &lt;code&gt;n&lt;/code&gt; are &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Possible reorderings: &lt;code&gt;10&lt;/code&gt; (leading digit not zero), &lt;code&gt;01&lt;/code&gt; (leading digit is zero, so invalid).&lt;/li&gt;
&lt;li&gt;  Is &lt;code&gt;10&lt;/code&gt; a power of two? No.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Output: &lt;code&gt;false&lt;/code&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;The constraints tell us &lt;code&gt;1 &amp;lt;= n &amp;lt;= 10^9&lt;/code&gt;. This is a crucial piece of information!&lt;/p&gt;




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

&lt;p&gt;When you see a problem asking if you can "reorder digits" to form something specific, a common technique springs to mind: &lt;strong&gt;digit frequency counting!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think about it: if two numbers are just reorderings of each other, they &lt;em&gt;must&lt;/em&gt; have the exact same count of each digit. For example, &lt;code&gt;123&lt;/code&gt; and &lt;code&gt;312&lt;/code&gt; both have one &lt;code&gt;1&lt;/code&gt;, one &lt;code&gt;2&lt;/code&gt;, and one &lt;code&gt;3&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, our problem boils down to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Take the input number &lt;code&gt;n&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Count how many times each digit (0-9) appears in &lt;code&gt;n&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Now, how do we check if &lt;em&gt;any&lt;/em&gt; power of two can be formed from these digits? Instead of trying to &lt;em&gt;generate&lt;/em&gt; permutations of &lt;code&gt;n&lt;/code&gt; (which can be a lot!), what if we just check a list of &lt;em&gt;known&lt;/em&gt; powers of two?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is where the constraint &lt;code&gt;n &amp;lt;= 10^9&lt;/code&gt; becomes our best friend.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;n&lt;/code&gt; can have at most 10 digits (e.g., &lt;code&gt;1,000,000,000&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  Powers of two quickly grow!

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;2^0 = 1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;2^1 = 2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  ...&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;2^9 = 512&lt;/code&gt; (3 digits)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;2^10 = 1024&lt;/code&gt; (4 digits)&lt;/li&gt;
&lt;li&gt;  ...&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;2^29 = 536,870,912&lt;/code&gt; (9 digits)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;2^30 = 1,073,741,824&lt;/code&gt; (10 digits)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;2^31&lt;/code&gt; would exceed the &lt;code&gt;int&lt;/code&gt; limit and also have too many digits if &lt;code&gt;n&lt;/code&gt; maxes out at 10.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;So, we only need to check a relatively &lt;em&gt;small list&lt;/em&gt; of powers of two (from &lt;code&gt;2^0&lt;/code&gt; up to &lt;code&gt;2^30&lt;/code&gt; or so). For each power of two in this list, we can count its digit frequencies and compare them to the digit frequencies of our input &lt;code&gt;n&lt;/code&gt;. If we find a match, we've solved it!&lt;/p&gt;




&lt;h3&gt;
  
  
  🪜 Approach: Step-by-Step Logic
&lt;/h3&gt;

&lt;p&gt;Here's the detailed plan based on our intuition:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Count Digits for &lt;code&gt;n&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Create an array (or vector) of size 10, initialized to zeros. Each index &lt;code&gt;i&lt;/code&gt; will store the count of digit &lt;code&gt;i&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Convert &lt;code&gt;n&lt;/code&gt; to a string.&lt;/li&gt;
&lt;li&gt;  Iterate through each character (digit) in the string, convert it back to an integer, and increment its count in our array.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Iterate Powers of Two&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Start a loop from &lt;code&gt;i = 0&lt;/code&gt; up to &lt;code&gt;30&lt;/code&gt; (or &lt;code&gt;31&lt;/code&gt; if you want to be super safe, covering &lt;code&gt;2^0&lt;/code&gt; to &lt;code&gt;2^30&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  In each iteration, calculate &lt;code&gt;current_power_of_2 = 1 &amp;lt;&amp;lt; i&lt;/code&gt; (which is a fast way to get &lt;code&gt;2^i&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Count Digits for &lt;code&gt;current_power_of_2&lt;/code&gt;&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  For each &lt;code&gt;current_power_of_2&lt;/code&gt;, perform the same digit counting process as we did for &lt;code&gt;n&lt;/code&gt;. Store these counts in a &lt;em&gt;temporary&lt;/em&gt; array.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Compare Digit Counts&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Compare the digit count array of &lt;code&gt;n&lt;/code&gt; (from Step 1) with the digit count array of &lt;code&gt;current_power_of_2&lt;/code&gt; (from Step 3).&lt;/li&gt;
&lt;li&gt;  If both arrays are &lt;em&gt;identical&lt;/em&gt; (meaning they have the same counts for all digits 0-9), then we've found a power of two that can be formed by reordering &lt;code&gt;n&lt;/code&gt;'s digits. In this case, immediately return &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;No Match Found&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If the loop finishes without finding any matching power of two, it means no such rearrangement exists. Return &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why this works:&lt;/strong&gt; The leading digit constraint ("leading digit is not zero") is automatically handled because powers of two (other than &lt;code&gt;2^0=1&lt;/code&gt;) are always positive and never start with zero. Our digit counting only cares about the set of digits, not their order initially. If the digit counts match, it means we &lt;em&gt;can&lt;/em&gt; form that power of two, and since it's a valid power of two, its leading digit will never be zero (unless it's a single-digit '0', which isn't a power of two, or if &lt;code&gt;n&lt;/code&gt; itself were &lt;code&gt;0&lt;/code&gt;, but &lt;code&gt;n &amp;gt;= 1&lt;/code&gt;).&lt;/p&gt;




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

&lt;p&gt;Here's the C++ implementation of our approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&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="nl"&gt;public:&lt;/span&gt;
    &lt;span class="c1"&gt;// Helper function to count digit frequencies for a given number&lt;/span&gt;
    &lt;span class="c1"&gt;// It returns a vector of size 10, where index i stores the count of digit i.&lt;/span&gt;
    &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getDigitCounts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&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;// Initialize counts for digits 0-9 to zero&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;to_string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Convert the number to a string&lt;/span&gt;

        &lt;span class="c1"&gt;// Iterate through each character (digit) in the string&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;c&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="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;counts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="sc"&gt;'0'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Increment the count for the corresponding digit&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;counts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Return the frequency map&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;reorderedPowerOf2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Step 1: Get digit frequency counts for the input number 'n'&lt;/span&gt;
        &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;n_digit_counts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getDigitCounts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Step 2: Iterate through all relevant powers of 2&lt;/span&gt;
        &lt;span class="c1"&gt;// We check powers from 2^0 up to 2^30.&lt;/span&gt;
        &lt;span class="c1"&gt;// 2^0 = 1&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
        &lt;span class="c1"&gt;// 2^29 = 536,870,912 (9 digits)&lt;/span&gt;
        &lt;span class="c1"&gt;// 2^30 = 1,073,741,824 (10 digits)&lt;/span&gt;
        &lt;span class="c1"&gt;// Since n &amp;lt;= 10^9, n can have at most 10 digits.&lt;/span&gt;
        &lt;span class="c1"&gt;// Any power of two with more than 10 digits, or fewer digits but different counts,&lt;/span&gt;
        &lt;span class="c1"&gt;// will automatically not match. So checking up to 2^30 is sufficient.&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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;0&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;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;31&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="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Loop from i=0 to i=30 (inclusive)&lt;/span&gt;
            &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;powerOf2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&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;// Calculate 2 raised to the power of i&lt;/span&gt;

            &lt;span class="c1"&gt;// Step 3: Get digit frequency counts for the current power of 2&lt;/span&gt;
            &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;current_power_digit_counts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getDigitCounts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;powerOf2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Step 4: Compare the digit frequency counts&lt;/span&gt;
            &lt;span class="c1"&gt;// If the counts are identical, it means we can reorder the digits of 'n'&lt;/span&gt;
            &lt;span class="c1"&gt;// to form this 'powerOf2'.&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n_digit_counts&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;current_power_digit_counts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Found a match, so return true&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// If the loop completes without finding any matching power of two,&lt;/span&gt;
        &lt;span class="c1"&gt;// then it's not possible to reorder 'n' into a power of two.&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&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;p&gt;Let's break down how efficient our solution is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Time Complexity:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;n&lt;/code&gt; can be up to &lt;code&gt;10^9&lt;/code&gt;, which means it has at most 10 digits (i.e., &lt;code&gt;log10(n)&lt;/code&gt; digits). Let &lt;code&gt;D&lt;/code&gt; be the maximum number of digits (here, &lt;code&gt;D = 10&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  The &lt;code&gt;getDigitCounts&lt;/code&gt; function:

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;to_string(num)&lt;/code&gt; takes &lt;code&gt;O(D)&lt;/code&gt; time.&lt;/li&gt;
&lt;li&gt;  The loop iterates &lt;code&gt;D&lt;/code&gt; times.&lt;/li&gt;
&lt;li&gt;  So, &lt;code&gt;getDigitCounts&lt;/code&gt; is &lt;code&gt;O(D)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  The main &lt;code&gt;reorderedPowerOf2&lt;/code&gt; function:

&lt;ul&gt;
&lt;li&gt;  Calls &lt;code&gt;getDigitCounts(n)&lt;/code&gt; once: &lt;code&gt;O(D)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  The loop runs &lt;code&gt;31&lt;/code&gt; times (for &lt;code&gt;i&lt;/code&gt; from 0 to 30). Let &lt;code&gt;P&lt;/code&gt; be the number of powers of two we check (here, &lt;code&gt;P = 31&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  Inside the loop, &lt;code&gt;getDigitCounts(powerOf2)&lt;/code&gt; is called: &lt;code&gt;O(D)&lt;/code&gt; (since powers of two up to &lt;code&gt;2^30&lt;/code&gt; also have at most &lt;code&gt;D=10&lt;/code&gt; digits).&lt;/li&gt;
&lt;li&gt;  Comparing &lt;code&gt;std::vector&amp;lt;int&amp;gt;&lt;/code&gt; takes &lt;code&gt;O(10)&lt;/code&gt; which is &lt;code&gt;O(D)&lt;/code&gt; as it compares each of the 10 elements.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;  Total Time Complexity: &lt;code&gt;O(D) + P * (O(D) + O(D)) = O(D * P)&lt;/code&gt;.&lt;/li&gt;

&lt;li&gt;  Given &lt;code&gt;D = 10&lt;/code&gt; and &lt;code&gt;P = 31&lt;/code&gt;, this is roughly &lt;code&gt;10 * 31 = 310&lt;/code&gt; operations. This is extremely efficient! It's practically constant time.&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Space Complexity:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The &lt;code&gt;getDigitCounts&lt;/code&gt; function uses a &lt;code&gt;std::vector&amp;lt;int&amp;gt;&lt;/code&gt; of size 10 to store digit counts. This size is fixed, regardless of &lt;code&gt;n&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  The &lt;code&gt;reorderedPowerOf2&lt;/code&gt; function also uses two &lt;code&gt;std::vector&amp;lt;int&amp;gt;&lt;/code&gt; of size 10.&lt;/li&gt;
&lt;li&gt;  Total Space Complexity: &lt;code&gt;O(1)&lt;/code&gt; (constant space), as the storage required does not grow with the input &lt;code&gt;n&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;Digit Frequency for Permutations:&lt;/strong&gt; When a problem involves checking if numbers can be formed by "reordering" or "permuting" digits, counting digit frequencies is a powerful and often more efficient alternative than generating actual permutations.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Leverage Constraints:&lt;/strong&gt; The &lt;code&gt;n &amp;lt;= 10^9&lt;/code&gt; constraint was crucial. It limited our search space for powers of two to a very small, manageable number, turning what could be a complex permutation problem into a simple fixed-loop iteration.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Powers of Two:&lt;/strong&gt; Understanding how fast powers of two grow helps in setting appropriate loop bounds.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Helper Functions:&lt;/strong&gt; Breaking down repetitive logic (like digit counting) into a helper function makes your code cleaner, more readable, and easier to debug.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;This problem is a fantastic example of how understanding constraints and choosing the right data structure/technique can simplify a seemingly complex challenge! Keep practicing, and happy coding!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Submission Details:&lt;/strong&gt;&lt;br&gt;
Author Account: Vansh2710&lt;br&gt;
Time Published: 2026-04-04 00:24:08&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 204. Count Primes</title>
      <dc:creator>Vansh Aggarwal</dc:creator>
      <pubDate>Thu, 02 Apr 2026 17:56:01 +0000</pubDate>
      <link>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-204-count-primes-52eg</link>
      <guid>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-204-count-primes-52eg</guid>
      <description>&lt;h1&gt;
  
  
  Unleashing the Power of Primes: Your First Sieve of Eratosthenes Adventure!
&lt;/h1&gt;

&lt;p&gt;Hey there, future coding rockstars! 👋 Vansh here, ready to dive into another exciting LeetCode challenge with you. Today, we're tackling a classic problem that's super common in interviews and a fantastic way to learn about optimizing your code: &lt;strong&gt;204. Count Primes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Don't let the name scare you! We're going to break it down, understand the "aha!" moment, and build a super-efficient solution together. Ready? Let's roll!&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 The Problem Explained: Counting Our Prime Friends
&lt;/h2&gt;

&lt;p&gt;Imagine you're at a party, and you need to count all the "special" guests. In our coding world, these special guests are &lt;strong&gt;prime numbers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The problem asks us to:&lt;br&gt;
Given an integer &lt;code&gt;n&lt;/code&gt;, return the number of prime numbers that are &lt;strong&gt;strictly less than &lt;code&gt;n&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's a Prime Number?&lt;/strong&gt;&lt;br&gt;
A prime number is a natural number greater than 1 that has no positive divisors other than 1 and itself.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  2, 3, 5, 7, 11 are primes.&lt;/li&gt;
&lt;li&gt;  4 (divisible by 2), 6 (divisible by 2, 3), 9 (divisible by 3) are NOT primes.&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;Example 1: &lt;code&gt;n = 10&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We need primes less than 10.&lt;/li&gt;
&lt;li&gt;  Primes: 2, 3, 5, 7&lt;/li&gt;
&lt;li&gt;  Output: 4&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Example 2: &lt;code&gt;n = 0&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Primes are greater than 1. No primes less than 0.&lt;/li&gt;
&lt;li&gt;  Output: 0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Example 3: &lt;code&gt;n = 1&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  No primes less than 1.&lt;/li&gt;
&lt;li&gt;  Output: 0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The constraint &lt;code&gt;0 &amp;lt;= n &amp;lt;= 5 * 10^6&lt;/code&gt; tells us that &lt;code&gt;n&lt;/code&gt; can be quite large, hinting that a simple, brute-force approach might be too slow. This is where our optimization journey begins!&lt;/p&gt;


&lt;h2&gt;
  
  
  🤔 Intuition: From Naive to Nimble!
&lt;/h2&gt;

&lt;p&gt;So, how would you first approach this?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First thought (The Naive Way):&lt;/strong&gt;&lt;br&gt;
"Okay, I'll just check every number from 2 up to &lt;code&gt;n-1&lt;/code&gt;. For each number, I'll test if it's prime. How do I test if a number &lt;code&gt;k&lt;/code&gt; is prime? I'll try dividing &lt;code&gt;k&lt;/code&gt; by numbers from 2 up to &lt;code&gt;sqrt(k)&lt;/code&gt;. If none of them divide &lt;code&gt;k&lt;/code&gt; evenly, then &lt;code&gt;k&lt;/code&gt; is prime!"&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="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="nf"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;n&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="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isPrime&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;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;

&lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Helper&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isPrime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nf"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
&lt;span class="o"&gt;//&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;k&lt;/span&gt; &lt;span class="o"&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="o"&gt;//&lt;/span&gt;         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;
&lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach works! But let's think about efficiency. If &lt;code&gt;n&lt;/code&gt; is &lt;code&gt;5 * 10^6&lt;/code&gt;, checking &lt;code&gt;5 * 10^6&lt;/code&gt; numbers, and for each, doing &lt;code&gt;sqrt(5 * 10^6)&lt;/code&gt; divisions... that's going to be astronomically slow! We need something much faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The "Aha!" Moment (The Sieve of Eratosthenes):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of &lt;em&gt;checking&lt;/em&gt; each number individually, what if we could &lt;em&gt;eliminate&lt;/em&gt; non-prime numbers systematically?&lt;/p&gt;

&lt;p&gt;Imagine you have a list of all numbers from 2 to &lt;code&gt;n-1&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Start with the first prime number we know: &lt;strong&gt;2&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Since 2 is prime, we know all its multiples (4, 6, 8, 10, 12...) cannot be prime. Let's &lt;strong&gt;cross them out!&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Move to the next number that hasn't been crossed out: &lt;strong&gt;3&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt; Since 3 is prime, cross out all its multiples (6, 9, 12, 15...). Notice that 6 and 12 were already crossed out by 2 – that's perfectly fine!&lt;/li&gt;
&lt;li&gt; Move to the next unmarked number: &lt;strong&gt;5&lt;/strong&gt;. (4 was crossed out by 2). Cross out its multiples (10, 15, 20...).&lt;/li&gt;
&lt;li&gt; Keep repeating this process!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By the end, any number that is &lt;em&gt;not&lt;/em&gt; crossed out must be prime! This brilliant technique is called the &lt;strong&gt;Sieve of Eratosthenes&lt;/strong&gt;, and it's perfect for finding all primes up to a certain limit.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Approach: The Sieve in Action!
&lt;/h2&gt;

&lt;p&gt;Let's walk through the steps of implementing the Sieve of Eratosthenes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialize a "Primes Tracker":&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Create a boolean array (or an integer array where 1 means true and 0 means false) called &lt;code&gt;is_prime&lt;/code&gt; of size &lt;code&gt;n&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Initialize all entries from &lt;code&gt;is_prime[2]&lt;/code&gt; to &lt;code&gt;is_prime[n-1]&lt;/code&gt; as &lt;code&gt;true&lt;/code&gt; (or 1), assuming they are prime for now.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;is_prime[0]&lt;/code&gt; and &lt;code&gt;is_prime[1]&lt;/code&gt; should be &lt;code&gt;false&lt;/code&gt; (or 0), because 0 and 1 are not prime.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Start Sieving (The Main Loop):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We'll iterate with a variable &lt;code&gt;p&lt;/code&gt; starting from &lt;code&gt;2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  The loop should continue as long as &lt;code&gt;p * p &amp;lt; n&lt;/code&gt;. Why &lt;code&gt;p * p&lt;/code&gt;? Because if &lt;code&gt;p&lt;/code&gt; is a prime, all its multiples less than &lt;code&gt;p * p&lt;/code&gt; (like &lt;code&gt;p * 2&lt;/code&gt;, &lt;code&gt;p * 3&lt;/code&gt;, up to &lt;code&gt;p * (p-1)&lt;/code&gt;) would have already been marked as not prime by smaller prime factors. For example, multiples of 5 less than 25 (like 10, 15, 20) would have been marked by 2 or 3.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Marking Multiples:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Inside the loop, if &lt;code&gt;is_prime[p]&lt;/code&gt; is still &lt;code&gt;true&lt;/code&gt; (meaning &lt;code&gt;p&lt;/code&gt; itself is a prime number):

&lt;ul&gt;
&lt;li&gt;  We know &lt;code&gt;p&lt;/code&gt; is prime, so all its multiples are not prime.&lt;/li&gt;
&lt;li&gt;  Start another inner loop from &lt;code&gt;i = p * p&lt;/code&gt; up to &lt;code&gt;n-1&lt;/code&gt;, incrementing by &lt;code&gt;p&lt;/code&gt; each time (&lt;code&gt;i += p&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;  Set &lt;code&gt;is_prime[i] = false&lt;/code&gt; (or 0) for all these multiples.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Count the Primes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  After the main loop finishes, all numbers that are still marked &lt;code&gt;true&lt;/code&gt; in our &lt;code&gt;is_prime&lt;/code&gt; array are prime numbers.&lt;/li&gt;
&lt;li&gt;  Iterate through the &lt;code&gt;is_prime&lt;/code&gt; array from &lt;code&gt;2&lt;/code&gt; up to &lt;code&gt;n-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  For every &lt;code&gt;is_prime[i]&lt;/code&gt; that is &lt;code&gt;true&lt;/code&gt;, increment a &lt;code&gt;count&lt;/code&gt; variable.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Return the Count:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The final &lt;code&gt;count&lt;/code&gt; is our answer!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's see this in C!&lt;/p&gt;




&lt;h2&gt;
  
  
  💻 Code: The Sieve in C
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt; // Required for malloc and free&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;countPrimes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle edge cases: No primes less than or equal to 2&lt;/span&gt;
    &lt;span class="k"&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;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 1. Create a boolean array "is_prime[0...n-1]" and initialize&lt;/span&gt;
    &lt;span class="c1"&gt;//    all entries as true (represented by 1). A value in is_prime[i] will&lt;/span&gt;
    &lt;span class="c1"&gt;//    finally be false (0) if i is Not a prime, else true (1).&lt;/span&gt;
    &lt;span class="c1"&gt;//    Using an int array as a boolean array where 1=true, 0=false.&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;is_prime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;malloc&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="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_prime&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Handle memory allocation failure&lt;/span&gt;
        &lt;span class="c1"&gt;// For LeetCode, this typically won't happen for given constraints,&lt;/span&gt;
        &lt;span class="c1"&gt;// but good practice in real-world C code.&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Initialize all numbers to be potentially prime&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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;0&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;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;is_prime&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 1 means true (potentially prime)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 0 and 1 are not prime numbers&lt;/span&gt;
    &lt;span class="n"&gt;is_prime&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&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;// 0 means false (not prime)&lt;/span&gt;
    &lt;span class="n"&gt;is_prime&lt;/span&gt;&lt;span class="p"&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;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 0 means false (not prime)&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. Start the Sieve process from p = 2&lt;/span&gt;
    &lt;span class="c1"&gt;//    We only need to iterate up to sqrt(n) because any composite number&lt;/span&gt;
    &lt;span class="c1"&gt;//    n must have a prime factor less than or equal to sqrt(n).&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// If is_prime[p] is still true, then it is a prime number&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_prime&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;]&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="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// 3. Mark all multiples of p as not prime (false)&lt;/span&gt;
            &lt;span class="c1"&gt;//    We start marking from p*p because any multiple smaller than p*p&lt;/span&gt;
            &lt;span class="c1"&gt;//    (e.g., 2*p, 3*p, etc.) would have already been marked by a&lt;/span&gt;
            &lt;span class="c1"&gt;//    smaller prime factor (e.g., 2, 3).&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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;p&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p&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;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&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="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;is_prime&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Mark as not prime&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 4. Count all prime numbers&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&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="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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;2&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;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_prime&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 5. Free the dynamically allocated memory&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_prime&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;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⏱️ Complexity Analysis
&lt;/h2&gt;

&lt;p&gt;Understanding how efficient our algorithm is, is just as important as writing the correct code!&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;  This might look intimidating, but it's incredibly efficient for finding all primes up to &lt;code&gt;N&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  The outer loop runs up to &lt;code&gt;sqrt(N)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  The inner loop (marking multiples) for each prime &lt;code&gt;p&lt;/code&gt; iterates &lt;code&gt;N/p&lt;/code&gt; times.&lt;/li&gt;
&lt;li&gt;  When you sum &lt;code&gt;N/p&lt;/code&gt; for all primes &lt;code&gt;p&lt;/code&gt; up to &lt;code&gt;N&lt;/code&gt;, it mathematically approximates to &lt;code&gt;N log log N&lt;/code&gt;. This is much faster than &lt;code&gt;O(N * sqrt(N))&lt;/code&gt; of the naive approach!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

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

&lt;ul&gt;
&lt;li&gt;  We use an array &lt;code&gt;is_prime&lt;/code&gt; of size &lt;code&gt;N&lt;/code&gt; to store the primality status of each number. This makes the space complexity directly proportional to &lt;code&gt;N&lt;/code&gt;.&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;The Sieve of Eratosthenes:&lt;/strong&gt; This is a fundamental algorithm for efficiently finding all prime numbers up to a specified limit. It's a must-know for competitive programming and interviews!&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Trade-off:&lt;/strong&gt; We use extra space (&lt;code&gt;O(N)&lt;/code&gt; for the &lt;code&gt;is_prime&lt;/code&gt; array) to achieve significantly faster time complexity (&lt;code&gt;O(N log log N)&lt;/code&gt;). This is a common pattern in algorithm design!&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Optimization &lt;code&gt;p * p&lt;/code&gt;:&lt;/strong&gt; Starting the inner loop from &lt;code&gt;p * p&lt;/code&gt; is a crucial optimization that prevents redundant work and makes the sieve faster.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Problem Recognition:&lt;/strong&gt; When you see problems asking for "all primes up to &lt;code&gt;N&lt;/code&gt;" or "counting primes less than &lt;code&gt;N&lt;/code&gt;" with large &lt;code&gt;N&lt;/code&gt;, think Sieve!&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Memory Management (in C/C++):&lt;/strong&gt; Don't forget to &lt;code&gt;free&lt;/code&gt; dynamically allocated memory (&lt;code&gt;malloc&lt;/code&gt;) to prevent memory leaks!&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Congratulations! You've just learned and implemented one of the coolest and most efficient prime-finding algorithms out there. Keep practicing, and you'll be a coding wizard in no time!&lt;/p&gt;

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




&lt;p&gt;&lt;em&gt;Authored by Vansh2710 | Published: 2026-04-02 23:25:05&lt;/em&gt;&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 204. Count Primes</title>
      <dc:creator>Vansh Aggarwal</dc:creator>
      <pubDate>Thu, 02 Apr 2026 17:50:06 +0000</pubDate>
      <link>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-204-count-primes-1d2d</link>
      <guid>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-204-count-primes-1d2d</guid>
      <description>&lt;h1&gt;
  
  
  Unlock the Primes: Your First Dive into Counting Primes (LeetCode 204)
&lt;/h1&gt;

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

&lt;p&gt;Vansh2710 here, your friendly neighborhood competitive programmer and technical writer. Today, we're going to tackle a classic LeetCode problem that's super common in interviews and a fantastic way to learn about efficient algorithms: &lt;strong&gt;Problem 204: Count Primes&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Don't let the "mathy" title scare you! We'll break it down piece by piece, find an awesome solution, and make sure you walk away feeling like a prime number pro. Ready? Let's dive in!&lt;/p&gt;




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

&lt;p&gt;The problem asks us to do one simple thing: given an integer &lt;code&gt;n&lt;/code&gt;, &lt;strong&gt;return the number of prime numbers that are strictly less than &lt;code&gt;n&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;"Strictly less than &lt;code&gt;n&lt;/code&gt;" means we're looking at numbers from &lt;code&gt;0&lt;/code&gt; up to &lt;code&gt;n-1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's look at a few examples to make it crystal clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Example 1: &lt;code&gt;n = 10&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Numbers strictly less than 10 are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.&lt;/li&gt;
&lt;li&gt;  Which of these are prime? A prime number is a natural number greater than 1 that has no positive divisors other than 1 and itself.&lt;/li&gt;
&lt;li&gt;  The primes are: &lt;strong&gt;2, 3, 5, 7&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;  So, the output is &lt;code&gt;4&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Example 2: &lt;code&gt;n = 0&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Numbers strictly less than 0? None!&lt;/li&gt;
&lt;li&gt;  Output: &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Example 3: &lt;code&gt;n = 1&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Numbers strictly less than 1? Only &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Is &lt;code&gt;0&lt;/code&gt; prime? No, primes must be greater than 1.&lt;/li&gt;
&lt;li&gt;  Output: &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Simple enough, right? The core challenge is &lt;em&gt;how&lt;/em&gt; to count these primes efficiently, especially when &lt;code&gt;n&lt;/code&gt; can be as large as &lt;code&gt;5 * 10^6&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Intuition: From Naive to "Aha!" Moment 💡
&lt;/h2&gt;

&lt;p&gt;Before we jump into the best solution, let's think about how we might &lt;em&gt;naively&lt;/em&gt; solve this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Naive Approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Start a counter for primes, initialized to &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; Loop through every number &lt;code&gt;i&lt;/code&gt; from &lt;code&gt;2&lt;/code&gt; up to &lt;code&gt;n-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; For each &lt;code&gt;i&lt;/code&gt;, check if it's prime. How? By trying to divide &lt;code&gt;i&lt;/code&gt; by every number &lt;code&gt;j&lt;/code&gt; from &lt;code&gt;2&lt;/code&gt; up to &lt;code&gt;sqrt(i)&lt;/code&gt;. If &lt;code&gt;i&lt;/code&gt; is divisible by any &lt;code&gt;j&lt;/code&gt; (meaning &lt;code&gt;i % j == 0&lt;/code&gt;), then &lt;code&gt;i&lt;/code&gt; is not prime. If it's not divisible by any &lt;code&gt;j&lt;/code&gt;, then &lt;code&gt;i&lt;/code&gt; is prime, and we increment our counter.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach works, but it's incredibly slow. Imagine &lt;code&gt;n&lt;/code&gt; is &lt;code&gt;5 * 10^6&lt;/code&gt;. For each number up to &lt;code&gt;n&lt;/code&gt;, you're doing another loop that goes up to its square root. The total operations would be roughly &lt;code&gt;n * sqrt(n)&lt;/code&gt;, which for &lt;code&gt;n = 5 * 10^6&lt;/code&gt; is a massive number (~10 billion operations!). This will definitely give us a "Time Limit Exceeded" (TLE) error on LeetCode.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The "Aha!" Moment - The Sieve of Eratosthenes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What if, instead of repeatedly checking divisibility for &lt;em&gt;each&lt;/em&gt; number, we could mark off &lt;em&gt;non-prime&lt;/em&gt; numbers more efficiently?&lt;/p&gt;

&lt;p&gt;This is where the ancient Greek mathematician Eratosthenes comes in with his brilliant "sieve" method. Think of it like a strainer:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Imagine you have a list of all numbers up to &lt;code&gt;n-1&lt;/code&gt;. Initially, assume they are all prime.&lt;/li&gt;
&lt;li&gt; Start with the first prime number, &lt;code&gt;2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Aha!&lt;/strong&gt; If &lt;code&gt;2&lt;/code&gt; is prime, then all its multiples (&lt;code&gt;4, 6, 8, 10, ...&lt;/code&gt;) &lt;em&gt;cannot&lt;/em&gt; be prime! Let's mark them as non-prime.&lt;/li&gt;
&lt;li&gt; Move to the next &lt;em&gt;unmarked&lt;/em&gt; number. That's &lt;code&gt;3&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Aha again!&lt;/strong&gt; If &lt;code&gt;3&lt;/code&gt; is unmarked, it must be prime. All its multiples (&lt;code&gt;6, 9, 12, 15, ...&lt;/code&gt;) &lt;em&gt;cannot&lt;/em&gt; be prime. Mark them off! (Note: &lt;code&gt;6&lt;/code&gt; was already marked by &lt;code&gt;2&lt;/code&gt;, which is fine.)&lt;/li&gt;
&lt;li&gt; Continue this process. The numbers that remain unmarked must be prime.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the &lt;strong&gt;Sieve of Eratosthenes&lt;/strong&gt;, and it's super efficient for finding all primes up to a given limit!&lt;/p&gt;




&lt;h2&gt;
  
  
  Approach: Sieving Our Way to Primes
&lt;/h2&gt;

&lt;p&gt;Let's formalize the Sieve of Eratosthenes step-by-step:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Initialize a boolean array:&lt;/strong&gt; Create an array, let's call it &lt;code&gt;is_prime&lt;/code&gt;, of size &lt;code&gt;n&lt;/code&gt;. Initialize all its elements to &lt;code&gt;true&lt;/code&gt;. &lt;code&gt;is_prime[i]&lt;/code&gt; will be &lt;code&gt;true&lt;/code&gt; if &lt;code&gt;i&lt;/code&gt; is considered prime, and &lt;code&gt;false&lt;/code&gt; otherwise.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Handle Base Cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Numbers &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; are not prime. So, set &lt;code&gt;is_prime[0] = false&lt;/code&gt; and &lt;code&gt;is_prime[1] = false&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The Sieving Process:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Loop through numbers &lt;code&gt;p&lt;/code&gt; starting from &lt;code&gt;2&lt;/code&gt; up to &lt;code&gt;sqrt(n)&lt;/code&gt;. Why &lt;code&gt;sqrt(n)&lt;/code&gt;? Because if a number &lt;code&gt;k&lt;/code&gt; has a prime factor larger than &lt;code&gt;sqrt(k)&lt;/code&gt;, it must also have a prime factor smaller than &lt;code&gt;sqrt(k)&lt;/code&gt;. So, by the time we reach &lt;code&gt;sqrt(n)&lt;/code&gt;, all composite numbers less than &lt;code&gt;n&lt;/code&gt; will have already been marked by their smaller prime factors.&lt;/li&gt;
&lt;li&gt;  Inside this loop, check if &lt;code&gt;is_prime[p]&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;  If &lt;code&gt;is_prime[p]&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;, it means &lt;code&gt;p&lt;/code&gt; is a prime number.&lt;/li&gt;
&lt;li&gt;  Now, mark all multiples of &lt;code&gt;p&lt;/code&gt; as not prime. Start marking from &lt;code&gt;p * p&lt;/code&gt; up to &lt;code&gt;n-1&lt;/code&gt;, with increments of &lt;code&gt;p&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;  Why start from &lt;code&gt;p * p&lt;/code&gt;? Because any multiple &lt;code&gt;k * p&lt;/code&gt; where &lt;code&gt;k &amp;lt; p&lt;/code&gt; would have already been marked by a smaller prime factor &lt;code&gt;k&lt;/code&gt;. For example, when &lt;code&gt;p=3&lt;/code&gt;, we don't need to mark &lt;code&gt;3*2=6&lt;/code&gt; because &lt;code&gt;6&lt;/code&gt; would have already been marked when &lt;code&gt;p=2&lt;/code&gt;. We only need to mark &lt;code&gt;3*3=9&lt;/code&gt;, &lt;code&gt;3*4=12&lt;/code&gt;, and so on.&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;Count the Primes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  After the sieving process is complete, iterate through the &lt;code&gt;is_prime&lt;/code&gt; array from index &lt;code&gt;2&lt;/code&gt; up to &lt;code&gt;n-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Count how many &lt;code&gt;is_prime[i]&lt;/code&gt; values are still &lt;code&gt;true&lt;/code&gt;. This count is your answer!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's walk through &lt;code&gt;n = 10&lt;/code&gt; again with the Sieve:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;code&gt;is_prime&lt;/code&gt; array of size 10: &lt;code&gt;[T, T, T, T, T, T, T, T, T, T]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; Mark &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; as false: &lt;code&gt;[F, F, T, T, T, T, T, T, T, T]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Sieving Loop (p up to sqrt(10) ≈ 3):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;p = 2&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;is_prime[2]&lt;/code&gt; is &lt;code&gt;T&lt;/code&gt;. So, 2 is prime.&lt;/li&gt;
&lt;li&gt;  Mark multiples of 2 starting from &lt;code&gt;2*2=4&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;is_prime[4] = F&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;is_prime[6] = F&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;is_prime[8] = F&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  Array becomes: &lt;code&gt;[F, F, T, T, F, T, F, T, F, T]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;p = 3&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;is_prime[3]&lt;/code&gt; is &lt;code&gt;T&lt;/code&gt;. So, 3 is prime.&lt;/li&gt;
&lt;li&gt;  Mark multiples of 3 starting from &lt;code&gt;3*3=9&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;is_prime[9] = F&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  Array becomes: &lt;code&gt;[F, F, T, T, F, T, F, T, F, F]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; Loop ends (next &lt;code&gt;p&lt;/code&gt; would be 4, &lt;code&gt;4 &amp;gt; sqrt(10)&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Count:&lt;/strong&gt; Iterate from &lt;code&gt;i = 2&lt;/code&gt; to &lt;code&gt;9&lt;/code&gt;:

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;is_prime[2]&lt;/code&gt; is &lt;code&gt;T&lt;/code&gt; (count = 1)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;is_prime[3]&lt;/code&gt; is &lt;code&gt;T&lt;/code&gt; (count = 2)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;is_prime[5]&lt;/code&gt; is &lt;code&gt;T&lt;/code&gt; (count = 3)&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;is_prime[7]&lt;/code&gt; is &lt;code&gt;T&lt;/code&gt; (count = 4)&lt;/li&gt;
&lt;li&gt;  Total count: &lt;code&gt;4&lt;/code&gt;. Perfect!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Code 🧑‍💻
&lt;/h2&gt;

&lt;p&gt;Here's the C implementation of the Sieve of Eratosthenes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdbool.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt; // For boolean type&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt;  // For malloc&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;countPrimes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle edge cases where n is too small to contain any primes&lt;/span&gt;
    &lt;span class="k"&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;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a boolean array `is_prime` of size `n`&lt;/span&gt;
    &lt;span class="c1"&gt;// Initialize all entries as true. A value of true at `is_prime[i]`&lt;/span&gt;
    &lt;span class="c1"&gt;// will mean that i is potentially prime.&lt;/span&gt;
    &lt;span class="n"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;is_prime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;malloc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_prime&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Handle memory allocation failure&lt;/span&gt;
        &lt;span class="k"&gt;return&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;// Or throw an error, depending on desired behavior&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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;0&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;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;is_prime&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="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 0 and 1 are not prime numbers&lt;/span&gt;
    &lt;span class="n"&gt;is_prime&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;is_prime&lt;/span&gt;&lt;span class="p"&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="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Start the Sieve process from p = 2&lt;/span&gt;
    &lt;span class="c1"&gt;// We only need to iterate up to sqrt(n)&lt;/span&gt;
    &lt;span class="c1"&gt;// Note: The loop condition `p * p &amp;lt; n` works because if `p` exceeds `sqrt(n)`,&lt;/span&gt;
    &lt;span class="c1"&gt;// then `p*p` would exceed `n`.&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// If is_prime[p] is still true, then it is a prime number&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_prime&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Mark all multiples of p as not prime.&lt;/span&gt;
            &lt;span class="c1"&gt;// Start from p*p, because smaller multiples (like 2*p, 3*p, etc.)&lt;/span&gt;
            &lt;span class="c1"&gt;// would have already been marked by their smaller prime factors (2, 3, etc.).&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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;p&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p&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;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&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="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;is_prime&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="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Count all prime numbers&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&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="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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;2&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;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_prime&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="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Free the dynamically allocated memory&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;is_prime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;is_prime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Good practice to set pointer to NULL after freeing&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&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;Understanding how efficient our algorithm is crucial in competitive programming.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;  The outer loop runs up to &lt;code&gt;sqrt(n)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  The inner loop (marking multiples) runs for &lt;code&gt;n/p&lt;/code&gt; times for each prime &lt;code&gt;p&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  The total number of operations is approximately &lt;code&gt;n/2 + n/3 + n/5 + ...&lt;/code&gt; for all primes &lt;code&gt;p&lt;/code&gt; up to &lt;code&gt;n&lt;/code&gt;. This sum is mathematically proven to be &lt;code&gt;O(n log log n)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  For &lt;code&gt;n = 5 * 10^6&lt;/code&gt;, &lt;code&gt;log log n&lt;/code&gt; is a very small factor (around 2-3). This makes the Sieve extremely fast, almost linear &lt;code&gt;O(n)&lt;/code&gt;. Much better than &lt;code&gt;O(n * sqrt(n))&lt;/code&gt;!&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

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

&lt;ul&gt;
&lt;li&gt;  We use a boolean array &lt;code&gt;is_prime&lt;/code&gt; of size &lt;code&gt;n&lt;/code&gt; to store the primality status of each number. This requires &lt;code&gt;n&lt;/code&gt; boolean values, leading to &lt;code&gt;O(n)&lt;/code&gt; space complexity.&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;Sieve of Eratosthenes:&lt;/strong&gt; This is the go-to algorithm for finding all prime numbers up to a given limit &lt;code&gt;n&lt;/code&gt;. Memorize its logic!&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Optimization is Key:&lt;/strong&gt; The naive approach is easy to think of but too slow for larger inputs. Understanding how to optimize, like marking multiples instead of repeated division checks, is fundamental.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Square Root Optimization:&lt;/strong&gt; The &lt;code&gt;p * p &amp;lt; n&lt;/code&gt; (or &lt;code&gt;p &amp;lt; sqrt(n)&lt;/code&gt;) condition for the outer loop is a common optimization trick in primality tests and sieving algorithms.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Memory Management (C/C++):&lt;/strong&gt; Remember to &lt;code&gt;malloc&lt;/code&gt; memory for dynamic arrays and &lt;code&gt;free&lt;/code&gt; it when you're done to prevent memory leaks!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And that's it! You've successfully conquered the Count Primes problem using a powerful and elegant algorithm. Give yourself a pat on the back!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Authored by Vansh2710 | Published: 2026-04-02 23:19:43&lt;/em&gt;&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 204. Count Primes</title>
      <dc:creator>Vansh Aggarwal</dc:creator>
      <pubDate>Thu, 02 Apr 2026 17:44:46 +0000</pubDate>
      <link>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-204-count-primes-1c87</link>
      <guid>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-204-count-primes-1c87</guid>
      <description>&lt;h1&gt;
  
  
  Master the Sieve! Counting Primes Efficiently (LeetCode 204)
&lt;/h1&gt;

&lt;p&gt;Hey there, aspiring competitive programmer! 👋 Vansh here, ready to tackle another classic LeetCode problem that's super common in interviews and a fantastic way to learn about algorithm optimization. Today, we're diving into problem 204: "Count Primes."&lt;/p&gt;

&lt;p&gt;Don't let the name scare you! Prime numbers might sound complex, but the core idea is simple, and the trick to solving this efficiently is a beautiful algorithm called the &lt;strong&gt;Sieve of Eratosthenes&lt;/strong&gt;. Let's unravel it together!&lt;/p&gt;




&lt;h3&gt;
  
  
  🌟 The Problem: Simple Yet Tricky!
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem Statement:&lt;/strong&gt; Given an integer &lt;code&gt;n&lt;/code&gt;, your task is to return the count of prime numbers that are &lt;strong&gt;strictly less than &lt;code&gt;n&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wait, what's a prime number?&lt;/strong&gt;&lt;br&gt;
Great question! A prime number is a natural number greater than 1 that has no positive divisors other than 1 and itself.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Examples of primes:&lt;/strong&gt; 2, 3, 5, 7, 11, 13, ...&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Examples of non-primes (composite numbers):&lt;/strong&gt; 4 (divisible by 2), 6 (divisible by 2, 3), 9 (divisible by 3), ...&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Important:&lt;/strong&gt; 0 and 1 are &lt;strong&gt;not&lt;/strong&gt; considered prime numbers.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Example 1:&lt;/strong&gt; &lt;code&gt;n = 10&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Numbers strictly less than 10 are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.&lt;/li&gt;
&lt;li&gt;  Out of these, the primes are: 2, 3, 5, 7.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Output:&lt;/strong&gt; 4&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Example 2:&lt;/strong&gt; &lt;code&gt;n = 0&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  No numbers are strictly less than 0.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Output:&lt;/strong&gt; 0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Example 3:&lt;/strong&gt; &lt;code&gt;n = 1&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  No numbers are strictly less than 1 that can be prime.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Output:&lt;/strong&gt; 0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The constraints tell us &lt;code&gt;n&lt;/code&gt; can be up to &lt;code&gt;5 * 10^6&lt;/code&gt;. This hints that a simple, brute-force check for primality for every number won't be fast enough. We need something clever!&lt;/p&gt;


&lt;h3&gt;
  
  
  🤔 Intuition: From Brute-Force to "Aha!"
&lt;/h3&gt;

&lt;p&gt;My first thought for checking if a number &lt;code&gt;k&lt;/code&gt; is prime is to try dividing &lt;code&gt;k&lt;/code&gt; by every number from 2 up to &lt;code&gt;sqrt(k)&lt;/code&gt;. If none of them divide &lt;code&gt;k&lt;/code&gt; evenly, then &lt;code&gt;k&lt;/code&gt; is prime.&lt;/p&gt;

&lt;p&gt;If we apply this for &lt;em&gt;every&lt;/em&gt; number from 2 up to &lt;code&gt;n-1&lt;/code&gt;:&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="n"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;n&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;if&lt;/span&gt; &lt;span class="nf"&gt;isPrime&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;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And &lt;code&gt;isPrime(i)&lt;/code&gt; itself involves a loop. This approach quickly becomes too slow when &lt;code&gt;n&lt;/code&gt; gets large (like &lt;code&gt;5 * 10^6&lt;/code&gt;). Think about it: for &lt;code&gt;n=5*10^6&lt;/code&gt;, we'd be calling &lt;code&gt;isPrime&lt;/code&gt; millions of times, and each call can involve thousands of divisions. 🐌&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The "Aha!" Moment: Don't Repeat Work!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What if, instead of repeatedly checking divisibility, we could somehow &lt;em&gt;mark&lt;/em&gt; non-prime numbers as we discover them?&lt;/p&gt;

&lt;p&gt;Consider the number 2. It's prime!&lt;br&gt;
Now, any multiple of 2 (4, 6, 8, 10, 12, ...) cannot be prime, because they are all divisible by 2. So, we can just &lt;em&gt;mark them as not prime&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Next, consider 3. It's prime!&lt;br&gt;
Any multiple of 3 (6, 9, 12, 15, ...) cannot be prime. We can mark them. (Notice 6 was already marked by 2 – that's fine!)&lt;/p&gt;

&lt;p&gt;This filtering process, where you start with an assumption (all numbers are prime) and then systematically &lt;em&gt;cross out&lt;/em&gt; multiples of known primes, is exactly what the &lt;strong&gt;Sieve of Eratosthenes&lt;/strong&gt; does! It's like sifting flour – you start with everything and shake out the unwanted bits.&lt;/p&gt;




&lt;h3&gt;
  
  
  🚀 The Approach: Sieve of Eratosthenes Step-by-Step
&lt;/h3&gt;

&lt;p&gt;The Sieve of Eratosthenes is an ancient and incredibly efficient algorithm for finding all prime numbers up to any given limit. Here's how we'll implement it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initialize a "Primes" List:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Create a boolean array (or vector) called &lt;code&gt;isPrime&lt;/code&gt; of size &lt;code&gt;n&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Initialize all entries to &lt;code&gt;true&lt;/code&gt;. This means we initially assume all numbers from 0 to &lt;code&gt;n-1&lt;/code&gt; are prime.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Handle Non-Primes (0 and 1):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  We know 0 and 1 are not prime. So, immediately set &lt;code&gt;isPrime[0] = false&lt;/code&gt; and &lt;code&gt;isPrime[1] = false&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sieve Process:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Start a loop from &lt;code&gt;p = 2&lt;/code&gt; (the first prime number). This loop will go up to &lt;code&gt;sqrt(n-1)&lt;/code&gt;. Why &lt;code&gt;sqrt(n-1)&lt;/code&gt;? Because if a number &lt;code&gt;X&lt;/code&gt; has a divisor &lt;code&gt;d &amp;gt; sqrt(X)&lt;/code&gt;, then it must also have a divisor &lt;code&gt;X/d &amp;lt; sqrt(X)&lt;/code&gt;. So, we only need to check for prime factors up to the square root. Any composite number &lt;code&gt;X&lt;/code&gt; will have already been marked &lt;code&gt;false&lt;/code&gt; by one of its prime factors &lt;code&gt;p &amp;lt;= sqrt(X)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Inside the loop (for &lt;code&gt;p&lt;/code&gt;):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  Check if &lt;code&gt;isPrime[p]&lt;/code&gt; is still &lt;code&gt;true&lt;/code&gt;. If it is, &lt;code&gt;p&lt;/code&gt; is a prime number!&lt;/li&gt;
&lt;li&gt;  Now, &lt;code&gt;p&lt;/code&gt; is prime, so all its multiples are composite (not prime). We need to mark them as &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Start another inner loop from &lt;code&gt;i = p * p&lt;/code&gt; up to &lt;code&gt;n-1&lt;/code&gt;, incrementing &lt;code&gt;i&lt;/code&gt; by &lt;code&gt;p&lt;/code&gt; (&lt;code&gt;i += p&lt;/code&gt;).

&lt;ul&gt;
&lt;li&gt;  Set &lt;code&gt;isPrime[i] = false&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Why start from &lt;code&gt;p * p&lt;/code&gt;?&lt;/strong&gt; All multiples of &lt;code&gt;p&lt;/code&gt; smaller than &lt;code&gt;p * p&lt;/code&gt; (i.e., &lt;code&gt;2*p, 3*p, ..., (p-1)*p&lt;/code&gt;) would have already been marked by smaller prime factors. For example, &lt;code&gt;2*p&lt;/code&gt; would have been marked by &lt;code&gt;2&lt;/code&gt;, &lt;code&gt;3*p&lt;/code&gt; by &lt;code&gt;3&lt;/code&gt;, and so on. So, &lt;code&gt;p*p&lt;/code&gt; is the first multiple that might not have been marked yet.&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;Count the Primes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  After the sieving process is complete, iterate through the &lt;code&gt;isPrime&lt;/code&gt; array from &lt;code&gt;p = 2&lt;/code&gt; up to &lt;code&gt;n-1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  For every index &lt;code&gt;p&lt;/code&gt; where &lt;code&gt;isPrime[p]&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt;, increment a &lt;code&gt;count&lt;/code&gt; variable.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Return the Count:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The final &lt;code&gt;count&lt;/code&gt; is your answer!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's walk through &lt;code&gt;n = 10&lt;/code&gt; using this approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;code&gt;isPrime&lt;/code&gt; array of size 10: &lt;code&gt;[T, T, T, T, T, T, T, T, T, T]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt; Mark 0 and 1: &lt;code&gt;[F, F, T, T, T, T, T, T, T, T]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sieve Loop (p from 2 up to sqrt(9) = 3):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;p = 2&lt;/code&gt;: &lt;code&gt;isPrime[2]&lt;/code&gt; is &lt;code&gt;T&lt;/code&gt;. So, 2 is prime!

&lt;ul&gt;
&lt;li&gt;  Mark multiples of 2 from &lt;code&gt;2*2=4&lt;/code&gt; up to 9 as &lt;code&gt;F&lt;/code&gt;:&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;isPrime[4]=F&lt;/code&gt;, &lt;code&gt;isPrime[6]=F&lt;/code&gt;, &lt;code&gt;isPrime[8]=F&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;isPrime&lt;/code&gt; becomes: &lt;code&gt;[F, F, T, T, F, T, F, T, F, T]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;p = 3&lt;/code&gt;: &lt;code&gt;isPrime[3]&lt;/code&gt; is &lt;code&gt;T&lt;/code&gt;. So, 3 is prime!

&lt;ul&gt;
&lt;li&gt;  Mark multiples of 3 from &lt;code&gt;3*3=9&lt;/code&gt; up to 9 as &lt;code&gt;F&lt;/code&gt;:&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;isPrime[9]=F&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;isPrime&lt;/code&gt; becomes: &lt;code&gt;[F, F, T, T, F, T, F, T, F, F]&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  Loop ends because &lt;code&gt;p&lt;/code&gt; would be 4, which is &lt;code&gt;&amp;gt; sqrt(9)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Count Primes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;isPrime[2]&lt;/code&gt; is &lt;code&gt;T&lt;/code&gt; -&amp;gt; count = 1&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;isPrime[3]&lt;/code&gt; is &lt;code&gt;T&lt;/code&gt; -&amp;gt; count = 2&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;isPrime[4]&lt;/code&gt; is &lt;code&gt;F&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;isPrime[5]&lt;/code&gt; is &lt;code&gt;T&lt;/code&gt; -&amp;gt; count = 3&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;isPrime[6]&lt;/code&gt; is &lt;code&gt;F&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;isPrime[7]&lt;/code&gt; is &lt;code&gt;T&lt;/code&gt; -&amp;gt; count = 4&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;isPrime[8]&lt;/code&gt; is &lt;code&gt;F&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;isPrime[9]&lt;/code&gt; is &lt;code&gt;F&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; 4. Perfect!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  💻 Solution Code (C)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdbool.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="c1"&gt; // For malloc and free&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;countPrimes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Edge cases: 0, 1, 2 have no primes strictly less than them&lt;/span&gt;
    &lt;span class="k"&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;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 1. Initialize a boolean array 'isPrime' of size 'n'&lt;/span&gt;
    &lt;span class="c1"&gt;// and assume all numbers are prime initially.&lt;/span&gt;
    &lt;span class="c1"&gt;// Calloc initializes memory to zero (false for boolean)&lt;/span&gt;
    &lt;span class="c1"&gt;// We want true, so let's use malloc and then fill.&lt;/span&gt;
    &lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;isPrime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;malloc&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="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isPrime&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Handle memory allocation failure&lt;/span&gt;
        &lt;span class="k"&gt;return&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;// Or some error code&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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;0&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;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;isPrime&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="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 2. Mark 0 and 1 as not prime&lt;/span&gt;
    &lt;span class="n"&gt;isPrime&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;isPrime&lt;/span&gt;&lt;span class="p"&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="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// 3. Sieve Process&lt;/span&gt;
    &lt;span class="c1"&gt;// Loop from p = 2 up to sqrt(n-1)&lt;/span&gt;
    &lt;span class="c1"&gt;// p*p &amp;lt;= n is equivalent to p &amp;lt;= sqrt(n)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// If isPrime[p] is still true, then p is a prime number&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isPrime&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Mark all multiples of p as not prime&lt;/span&gt;
            &lt;span class="c1"&gt;// Start from p*p, as smaller multiples would have already been marked&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="kt"&gt;long&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;p&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;p&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;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&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="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;isPrime&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="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 4. Count the primes&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;count&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="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&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;2&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;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;n&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="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isPrime&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="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Free the dynamically allocated memory&lt;/span&gt;
    &lt;span class="n"&gt;free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isPrime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;isPrime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// 5. Return the total count&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;;&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 log log n)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Initializing the &lt;code&gt;isPrime&lt;/code&gt; array takes O(n) time.&lt;/li&gt;
&lt;li&gt;  The outer loop runs up to &lt;code&gt;sqrt(n)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  The inner loop (marking multiples) is the key. For each prime &lt;code&gt;p&lt;/code&gt;, it performs &lt;code&gt;n/p&lt;/code&gt; operations.&lt;/li&gt;
&lt;li&gt;  The sum of &lt;code&gt;n/p&lt;/code&gt; for all primes &lt;code&gt;p&lt;/code&gt; up to &lt;code&gt;n&lt;/code&gt; is approximately &lt;code&gt;n * (1/2 + 1/3 + 1/5 + ...)&lt;/code&gt; which is &lt;code&gt;O(n log log n)&lt;/code&gt;. This is highly efficient and much faster than &lt;code&gt;O(n * sqrt(n))&lt;/code&gt;!&lt;/li&gt;
&lt;li&gt;  Counting the primes takes O(n).&lt;/li&gt;
&lt;li&gt;  Overall, the dominant factor is &lt;code&gt;O(n log log n)&lt;/code&gt;.&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;  We use a boolean array &lt;code&gt;isPrime&lt;/code&gt; of size &lt;code&gt;n&lt;/code&gt; to store the primality status of each number. This takes O(n) space. For &lt;code&gt;n = 5 * 10^6&lt;/code&gt;, this is about 5 megabytes, which is perfectly acceptable.&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;Don't Brute-Force Primality for Ranges:&lt;/strong&gt; If you need to find &lt;em&gt;many&lt;/em&gt; primes up to a certain limit, the Sieve of Eratosthenes is almost always the way to go. Checking primality for each number individually is inefficient.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Sieve of Eratosthenes:&lt;/strong&gt; Understand its core idea: start with all numbers as potentially prime, then systematically eliminate multiples of known primes.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Optimization &lt;code&gt;p * p&lt;/code&gt;:&lt;/strong&gt; Starting the marking of multiples from &lt;code&gt;p * p&lt;/code&gt; is a crucial optimization. It avoids redundant work because smaller multiples would have already been marked by smaller prime factors.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Time Efficiency:&lt;/strong&gt; The &lt;code&gt;O(n log log n)&lt;/code&gt; complexity makes the Sieve extremely powerful for large inputs.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Memory Management (C/C++):&lt;/strong&gt; Remember to &lt;code&gt;malloc&lt;/code&gt; memory for dynamic arrays and &lt;code&gt;free&lt;/code&gt; it after you're done to prevent memory leaks!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This problem is a fantastic entry point into number theory algorithms and demonstrates how a clever insight can dramatically improve performance. Keep practicing, and you'll be a master of these techniques in no time! Happy coding!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Author Account:&lt;/strong&gt; Vansh2710&lt;br&gt;
&lt;strong&gt;Time Published:&lt;/strong&gt; 2026-04-02 23:14:04&lt;/p&gt;

</description>
      <category>leetcode</category>
      <category>dsa</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>LeetCode Solution: 240. Search a 2D Matrix II</title>
      <dc:creator>Vansh Aggarwal</dc:creator>
      <pubDate>Tue, 31 Mar 2026 18:51:35 +0000</pubDate>
      <link>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-240-search-a-2d-matrix-ii-5gga</link>
      <guid>https://dev.to/vansh_aggarwal_5fb2fff667/leetcode-solution-240-search-a-2d-matrix-ii-5gga</guid>
      <description>&lt;h1&gt;
  
  
  Search a 2D Matrix II: The Clever Corner Approach You Need to Know!
&lt;/h1&gt;

&lt;p&gt;Hey there, fellow coders! 👋 Vansh here, diving into another LeetCode adventure that looks tricky on the surface but has a surprisingly elegant solution. Today, we're tackling &lt;a href="https://leetcode.com/problems/search-a-2d-matrix-ii/" rel="noopener noreferrer"&gt;LeetCode 240: Search a 2D Matrix II&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This problem is a classic for a reason – it tests your ability to think outside the box and leverage unique properties of the input. If you've ever felt stuck with matrices, this one's a fantastic stepping stone! Let's unravel this mystery together.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: Finding Your Way in a Double-Sorted Grid
&lt;/h2&gt;

&lt;p&gt;Imagine you have a large grid of numbers, like a spreadsheet. This isn't just any grid, though; it has two very special properties:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Rows are Sorted:&lt;/strong&gt; If you look at any single row, the numbers go from smallest on the left to largest on the right.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Columns are Sorted:&lt;/strong&gt; If you look at any single column, the numbers go from smallest at the top to largest at the bottom.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your task? Given this special matrix and a &lt;code&gt;target&lt;/code&gt; number, you need to efficiently determine if the &lt;code&gt;target&lt;/code&gt; exists anywhere in the matrix.&lt;/p&gt;

&lt;p&gt;Let's look at an example to make it super clear:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1:&lt;/strong&gt;&lt;br&gt;
Input: &lt;code&gt;matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]]&lt;/code&gt;, &lt;code&gt;target = 5&lt;/code&gt;&lt;br&gt;
Output: &lt;code&gt;true&lt;/code&gt; (You can see 5 is right there in the second row, second column!)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 2:&lt;/strong&gt;&lt;br&gt;
Input: &lt;code&gt;matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21,23,26,30]]&lt;/code&gt;, &lt;code&gt;target = 20&lt;/code&gt;&lt;br&gt;
Output: &lt;code&gt;false&lt;/code&gt; (If you scan through, 20 isn't present in this matrix.)&lt;/p&gt;

&lt;p&gt;The key here is "efficiently". A brute-force search (checking every single number) would work, but can we do better? Given the sorted nature, probably!&lt;/p&gt;


&lt;h2&gt;
  
  
  Intuition: Where to Start Looking?
&lt;/h2&gt;

&lt;p&gt;When dealing with sorted data, binary search often comes to mind. You could run a binary search on each row, but that would be &lt;code&gt;O(m * log n)&lt;/code&gt; (m rows, log n for each search). Can we do even better?&lt;/p&gt;

&lt;p&gt;The real "aha!" moment comes when you realize that &lt;em&gt;both&lt;/em&gt; sorting properties give us powerful information. Where in the matrix can we start such that if we compare our current number to the &lt;code&gt;target&lt;/code&gt;, we can eliminate a significant portion of the search space?&lt;/p&gt;

&lt;p&gt;Consider the four corners:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Top-Left (smallest):&lt;/strong&gt; If &lt;code&gt;matrix[0][0]&lt;/code&gt; is too big, we can't eliminate anything useful. If it's too small, we don't know if we should go right or down. Not ideal.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Bottom-Right (largest):&lt;/strong&gt; Similar problem. If &lt;code&gt;matrix[m-1][n-1]&lt;/code&gt; is too small, we don't know where to go.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Top-Right (mix of small and large):&lt;/strong&gt; Ah, this is interesting!

&lt;ul&gt;
&lt;li&gt;  If &lt;code&gt;matrix[0][n-1]&lt;/code&gt; is &lt;em&gt;equal&lt;/em&gt; to &lt;code&gt;target&lt;/code&gt;, we found it!&lt;/li&gt;
&lt;li&gt;  If &lt;code&gt;matrix[0][n-1]&lt;/code&gt; is &lt;em&gt;greater&lt;/em&gt; than &lt;code&gt;target&lt;/code&gt;, what does that tell us? Since this is the largest element in its row, and all elements below it in its column are even larger, we know &lt;code&gt;target&lt;/code&gt; cannot be in the current column (or any element below the current position). So, we can safely move &lt;em&gt;left&lt;/em&gt; to a smaller column!&lt;/li&gt;
&lt;li&gt;  If &lt;code&gt;matrix[0][n-1]&lt;/code&gt; is &lt;em&gt;less&lt;/em&gt; than &lt;code&gt;target&lt;/code&gt;, what now? Since this is the smallest element at the end of its column, and all elements to its left in the current row are even smaller, we know &lt;code&gt;target&lt;/code&gt; cannot be in the current row (or any element to the left of the current position). So, we can safely move &lt;em&gt;down&lt;/em&gt; to a larger row!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Bottom-Left (mix of small and large):&lt;/strong&gt; This corner also works with similar logic! (Try it out as an exercise!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The top-right (or bottom-left) corner provides a perfect pivot point. From here, each comparison allows us to eliminate either a full row or a full column! This is incredibly efficient.&lt;/p&gt;


&lt;h2&gt;
  
  
  Approach: The "Staircase" Search
&lt;/h2&gt;

&lt;p&gt;Let's formalize the top-right corner approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Start at the Top-Right:&lt;/strong&gt; Initialize two pointers, &lt;code&gt;rowIndex = 0&lt;/code&gt; (first row) and &lt;code&gt;colIndex = n - 1&lt;/code&gt; (last column).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Iterate and Compare:&lt;/strong&gt; While &lt;code&gt;rowIndex&lt;/code&gt; is within the matrix bounds (&lt;code&gt;rowIndex &amp;lt; m&lt;/code&gt;) AND &lt;code&gt;colIndex&lt;/code&gt; is within the matrix bounds (&lt;code&gt;colIndex &amp;gt;= 0&lt;/code&gt;):

&lt;ul&gt;
&lt;li&gt;  Let &lt;code&gt;currentElement = matrix[rowIndex][colIndex]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Case 1: &lt;code&gt;currentElement == target&lt;/code&gt;&lt;/strong&gt;: We found our number! Return &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Case 2: &lt;code&gt;currentElement &amp;lt; target&lt;/code&gt;&lt;/strong&gt;: The &lt;code&gt;currentElement&lt;/code&gt; is too small. Since all elements to the &lt;em&gt;left&lt;/em&gt; in the current row are even smaller, and we need a larger value, the target &lt;em&gt;cannot&lt;/em&gt; be in the current row (left of &lt;code&gt;currentElement&lt;/code&gt;). We need to search in rows with potentially larger values. So, we move &lt;em&gt;down&lt;/em&gt; to the next row: &lt;code&gt;rowIndex++&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  &lt;strong&gt;Case 3: &lt;code&gt;currentElement &amp;gt; target&lt;/code&gt;&lt;/strong&gt;: The &lt;code&gt;currentElement&lt;/code&gt; is too large. Since all elements &lt;em&gt;below&lt;/em&gt; in the current column are even larger, and we need a smaller value, the target &lt;em&gt;cannot&lt;/em&gt; be in the current column (below &lt;code&gt;currentElement&lt;/code&gt;). We need to search in columns with potentially smaller values. So, we move &lt;em&gt;left&lt;/em&gt; to the previous column: &lt;code&gt;colIndex--&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Target Not Found:&lt;/strong&gt; If our loop finishes (either &lt;code&gt;rowIndex&lt;/code&gt; goes out of bounds or &lt;code&gt;colIndex&lt;/code&gt; goes out of bounds), it means we've exhausted all possible search paths without finding the target. Return &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This strategy looks like climbing down a staircase (or moving along a diagonal path), eliminating chunks of the matrix with each step.&lt;/p&gt;


&lt;h2&gt;
  
  
  Code: Bringing the Strategy to Life
&lt;/h2&gt;

&lt;p&gt;Here's the Python implementation of our "staircase" search:&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="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;searchMatrix&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;matrix&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;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="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Handle edge cases: empty matrix or empty rows
&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;matrix&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

        &lt;span class="n"&gt;rows&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;matrix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;cols&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;matrix&lt;/span&gt;&lt;span class="p"&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;# Start from the top-right corner
&lt;/span&gt;        &lt;span class="c1"&gt;# row pointer starts at the first row (index 0)
&lt;/span&gt;        &lt;span class="c1"&gt;# col pointer starts at the last column (index cols - 1)
&lt;/span&gt;        &lt;span class="n"&gt;rowIndex&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;colIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cols&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;# Continue search as long as we are within matrix boundaries
&lt;/span&gt;        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;rowIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;colIndex&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="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rowIndex&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="n"&gt;colIndex&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# Get the current element
&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# Target found!
&lt;/span&gt;                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
            &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;element&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="c1"&gt;# Current element is too small.
&lt;/span&gt;                &lt;span class="c1"&gt;# Since rows are sorted left-to-right, all elements to the left
&lt;/span&gt;                &lt;span class="c1"&gt;# in the current row are even smaller.
&lt;/span&gt;                &lt;span class="c1"&gt;# Since columns are sorted top-to-bottom, we need to go down
&lt;/span&gt;                &lt;span class="c1"&gt;# to potentially find larger values.
&lt;/span&gt;                &lt;span class="n"&gt;rowIndex&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;# element &amp;gt; target
&lt;/span&gt;                &lt;span class="c1"&gt;# Current element is too large.
&lt;/span&gt;                &lt;span class="c1"&gt;# Since columns are sorted top-to-bottom, all elements below
&lt;/span&gt;                &lt;span class="c1"&gt;# in the current column are even larger.
&lt;/span&gt;                &lt;span class="c1"&gt;# Since rows are sorted left-to-right, we need to go left
&lt;/span&gt;                &lt;span class="c1"&gt;# to potentially find smaller values.
&lt;/span&gt;                &lt;span class="n"&gt;colIndex&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;# If the loop finishes, the target was not found in the matrix
&lt;/span&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&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;Let's break down how efficient our solution is:&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;  In the worst-case scenario, our pointers &lt;code&gt;rowIndex&lt;/code&gt; or &lt;code&gt;colIndex&lt;/code&gt; will traverse at most &lt;code&gt;m&lt;/code&gt; rows and &lt;code&gt;n&lt;/code&gt; columns, respectively.&lt;/li&gt;
&lt;li&gt;  At each step, we either increment &lt;code&gt;rowIndex&lt;/code&gt; or decrement &lt;code&gt;colIndex&lt;/code&gt;, effectively reducing the search space.&lt;/li&gt;
&lt;li&gt;  We don't revisit cells or iterate over an entire row/column in each step. The total number of steps is proportional to &lt;code&gt;m + n&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  This is significantly better than &lt;code&gt;O(m * n)&lt;/code&gt; (brute force) or &lt;code&gt;O(m * log n)&lt;/code&gt; (binary search on each row).&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 only use a few extra variables (&lt;code&gt;rows&lt;/code&gt;, &lt;code&gt;cols&lt;/code&gt;, &lt;code&gt;rowIndex&lt;/code&gt;, &lt;code&gt;colIndex&lt;/code&gt;, &lt;code&gt;element&lt;/code&gt;) to store pointers and the current value.&lt;/li&gt;
&lt;li&gt;  This constant amount of extra space means our solution is very memory-efficient.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




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

&lt;p&gt;This problem is a fantastic lesson in algorithmic thinking:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Leverage Properties:&lt;/strong&gt; Always look for unique properties in your input data (like the double-sorted nature here). These properties are hints for more efficient algorithms.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Eliminate Search Space:&lt;/strong&gt; The core idea of many efficient algorithms is to eliminate as much of the potential search space as possible with each decision.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Optimal Starting Points:&lt;/strong&gt; The choice of where to start your search can drastically impact the algorithm's efficiency. Corners, especially top-right or bottom-left in this type of matrix, are often powerful pivot points.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Think Diagonally:&lt;/strong&gt; Sometimes the best path through a 2D structure isn't horizontal or vertical, but diagonal!&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Hope you enjoyed this dive into LeetCode 240! This problem is a great example of how a clever starting point and a simple set of rules can lead to a highly optimized solution. Keep practicing, and happy coding!&lt;/p&gt;




&lt;p&gt;Authored by Vansh2710 | Published: 2026-04-01 00:20:33&lt;/p&gt;

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