<?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>Forem: Prakhar Srivastava</title>
    <description>The latest articles on Forem by Prakhar Srivastava (@prakhar_srv).</description>
    <link>https://forem.com/prakhar_srv</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%2F3909129%2F5c563cfe-658c-4e09-a767-f5e320af4e2c.jpeg</url>
      <title>Forem: Prakhar Srivastava</title>
      <link>https://forem.com/prakhar_srv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/prakhar_srv"/>
    <language>en</language>
    <item>
      <title>Algorithmic intuition matters more than problem count in coding interviews</title>
      <dc:creator>Prakhar Srivastava</dc:creator>
      <pubDate>Thu, 07 May 2026 12:31:30 +0000</pubDate>
      <link>https://forem.com/codeintuition/algorithmic-intuition-matters-more-than-problem-count-in-coding-interviews-pep</link>
      <guid>https://forem.com/codeintuition/algorithmic-intuition-matters-more-than-problem-count-in-coding-interviews-pep</guid>
      <description>&lt;p&gt;Two engineers prep for the same cycle. One solves more than 500 problems and freezes when the medium doesn't look like anything from the practice list. The other solves a fraction of that and works the problem out from scratch on the screen. The variable that decides which way it goes isn't volume.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Volume practice builds memory of specific problems. It builds little of the skill that recognises which technique applies to a problem you've never seen.&lt;/li&gt;
&lt;li&gt;Learning science calls these near transfer (familiar problems) and far transfer (unfamiliar ones). Volume practice mostly trains near transfer.&lt;/li&gt;
&lt;li&gt;Real interviews test far transfer because the problem isn't labelled and won't match anything in the practice bank.&lt;/li&gt;
&lt;li&gt;Recognition is trainable. The training is explicit: read the problem for triggers, name the pattern, then write code.&lt;/li&gt;
&lt;li&gt;On the next problem you face, the recognition pass takes 30 seconds before you touch the keyboard. That pass is the gap.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Disclosure up front: I built Codeintuition, a structured learning platform for coding interviews. This post is about the recognition skill that decides whether volume practice converts to interview readiness, not about the product. The closing link goes to the longer version on my own blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  What 500 problems actually trains you to do
&lt;/h2&gt;

&lt;p&gt;Most coding interview advice tells you to solve more problems. There's a real reason this advice exists. Volume builds fluency: you stop being confused by syntax, you stop misreading constraints, and the interview minutes that used to go to typo-hunting start going to the actual problem. Past a few hundred problems, those skills are usually solid.&lt;/p&gt;

&lt;p&gt;What volume doesn't reliably build is the ability to read a problem you've never seen and decide which technique applies. That's a different skill, and the way most engineers practise actively trains around it. You attempt the problem, get stuck, glance at the LeetCode tags, notice it says &lt;code&gt;stack&lt;/code&gt;, and read a solution. The next time a stack problem shows up, you might recognise it. The time after, you might not. Recognition is being built by accident, not by design.&lt;/p&gt;

&lt;p&gt;In an interview the tag is gone. The problem statement isn't labelled &lt;code&gt;stack&lt;/code&gt; or &lt;code&gt;sliding window&lt;/code&gt; or &lt;code&gt;dynamic programming&lt;/code&gt;. So the skill that's been built by accident has to do work it's never been explicitly trained for. That's where the freeze comes from.&lt;/p&gt;

&lt;h2&gt;
  
  
  Near transfer vs far transfer
&lt;/h2&gt;

&lt;p&gt;There's a useful piece of language for this from the learning sciences, and it's worth borrowing because it predicts the failure mode precisely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Near transfer&lt;/strong&gt; is when you can solve a problem because it resembles one you've practised. You solved Two Sum with a hash map. The interviewer hands you Two Sum II with a sorted array. The visible details changed but the underlying idea is close enough that recognition fires.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Far transfer&lt;/strong&gt; is when you can solve a problem that doesn't resemble anything in your practice set, by reading the structure of the problem and constructing the approach from first principles. You see "minimum window of an array containing all characters of a target string" and you've never solved a window problem with a character constraint. You read the structure and construct a variable sliding window from scratch.&lt;/p&gt;

&lt;p&gt;Grinding 500 problems builds near transfer well. It does much less for far transfer. Whether far transfer is reliably teachable is a debate the &lt;a href="https://en.wikipedia.org/wiki/Transfer_of_learning" rel="noopener noreferrer"&gt;research on transfer of learning&lt;/a&gt; hasn't fully settled, but the evidence does support one specific intervention. Explicit instruction in &lt;strong&gt;when&lt;/strong&gt; and &lt;strong&gt;why&lt;/strong&gt; a method applies, not just &lt;strong&gt;how&lt;/strong&gt; to execute it, produces more transfer than practice alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  A worked example: monotonic stack on stock span
&lt;/h2&gt;

&lt;p&gt;Here's the kind of problem where the gap shows up. You're given an array of stock prices. For each day, find how many consecutive days before it had a price less than or equal to that day. The constraints don't mention "stack" anywhere.&lt;/p&gt;

&lt;p&gt;If you've practised the technique without practising the recognition, you'll probably try a nested loop first, hit &lt;code&gt;O(n^2)&lt;/code&gt;, and try to remember which problems you've seen with this shape. If recognition is trained, you read the problem's structure and three triggers fire:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"For each day" means you need an answer per element. Element-wise, not aggregate.&lt;/li&gt;
&lt;li&gt;"Consecutive days before it" means a directional search to the left.&lt;/li&gt;
&lt;li&gt;"A price less than or equal to" means a comparison condition between the current element and what's to its left.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Three triggers point at one technique: the previous closest occurrence pattern, implemented with a monotonic stack. The triggers are what you read off the problem statement. The pattern is what you write in code.&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;def&lt;/span&gt; &lt;span class="nf"&gt;stock_span&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;stack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="n"&gt;spans&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&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;price&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;stack&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="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;stack&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;stack&lt;/span&gt; &lt;span class="k"&gt;else&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="n"&gt;spans&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;stack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;spans&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The implementation is short and well documented across the internet. The bottleneck isn't writing the loop. It's noticing that "for each element, find the previous element satisfying a comparison condition" is one recognisable shape that always uses this technique. That's the recognition skill, and it's the part most prep doesn't train.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a recognition drill looks like
&lt;/h2&gt;

&lt;p&gt;Before solving a problem, do a 30 to 60 second pass on the statement alone. No code. The output of the pass is a name: which pattern, and why.&lt;/p&gt;

&lt;p&gt;For each technique you've learned, you should be able to name the two or three observable features of a problem statement that signal it applies. A few common ones from the techniques most coding interviews lean on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Variable sliding window: contiguous subarray or substring, plus a condition that holds across the window, plus an optimisation on window length. When all three appear, it's almost always this technique.&lt;/li&gt;
&lt;li&gt;Two pointers: a sorted array (or one you can sort) and a search for a pair or triple satisfying a target. The pointers move from the ends inward.&lt;/li&gt;
&lt;li&gt;Monotonic stack: per element answer, plus a directional search left or right, plus a comparison condition. Stock span fits. Next greater element fits.&lt;/li&gt;
&lt;li&gt;Backtracking: enumerate combinations or paths under a constraint, with the option to abandon a partial candidate when the constraint is violated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you start a problem, the drill is: read the constraints, list the features you see, name the technique, then start coding. If you can't name a technique in 60 seconds, you don't start coding. You re-read the constraints with the trigger checklists in front of you and try again. If you still can't, mark the problem and learn the missing feature before moving on.&lt;/p&gt;

&lt;p&gt;The first time, this feels artificial. After 30 problems, it stops feeling artificial because the features start firing automatically as you read.&lt;/p&gt;

&lt;h2&gt;
  
  
  The other thing prep tends to skip
&lt;/h2&gt;

&lt;p&gt;A bit of honesty before the close. Recognition isn't the only thing prep tends to skip. The conditions you practise under matter at least as much, and the default LeetCode loop is much friendlier than an interview.&lt;/p&gt;

&lt;p&gt;The default loop has the title visible, the difficulty visible, the company tags visible, the discussion section a click away, and no clock. None of those are present in the actual interview. If your reads of the problem have always been informed by the tag, the moment the tag disappears the read gets harder.&lt;/p&gt;

&lt;p&gt;A reasonable practice protocol for the last few weeks before an interview cycle:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cover the problem name with a sticky note before reading the constraints. Many problem names give away the technique.&lt;/li&gt;
&lt;li&gt;Set a 25 minute clock per medium. If you blow past it, that's data: the problem went to "still working" rather than "solved", and the next pass focuses on what slowed you down.&lt;/li&gt;
&lt;li&gt;Skip the discussion section on the first attempt. Read it after, only if your attempt didn't converge.&lt;/li&gt;
&lt;li&gt;Mix techniques. Three sliding window problems in a row trains nothing about recognition because the third is obvious by inertia. Three problems from different techniques force you to read the constraints.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can run all of this against any problem bank. It's a practice protocol, not a feature.&lt;/p&gt;

&lt;h2&gt;
  
  
  When grinding more is the right move
&lt;/h2&gt;

&lt;p&gt;Volume practice is the right call in two cases. First, when your fundamentals on a specific data structure or algorithm are weak enough that you can't implement it cleanly even with the technique handed to you. There, more reps fix the bottleneck directly. Second, when you're a few weeks out from an interview cycle and the goal is speed, not depth. The features you've already internalised get faster with reps.&lt;/p&gt;

&lt;p&gt;The cases where volume stops working are different. When implementation is solid but recognition under unfamiliar problems is the bottleneck, more reps don't move the needle because they aren't training what's broken.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the next problem looks like with this trained
&lt;/h2&gt;

&lt;p&gt;Six months out, you open an unfamiliar problem on a phone screen. The description mentions "for each element, count how many elements to the right are strictly greater before reaching one that's less or equal." Nothing in your practice list looks like it.&lt;/p&gt;

&lt;p&gt;Reading for features gets you somewhere. "For each element" is element-wise. "To the right" is directional. "Strictly greater" is a comparison condition. All three match a monotonic stack, written from the right toward the left. You're 30 seconds in and writing the loop.&lt;/p&gt;

&lt;p&gt;That's a trained skill. Volume helped, structure helped more, recognition is what closed the gap.&lt;/p&gt;

&lt;p&gt;If unfamiliar mediums still freeze you even after hundreds of problems, the bottleneck usually isn't implementation.&lt;/p&gt;

&lt;p&gt;It's recognition.&lt;/p&gt;

&lt;p&gt;I wrote a longer breakdown covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;feature checklists for six major interview patterns&lt;/li&gt;
&lt;li&gt;near transfer vs far transfer&lt;/li&gt;
&lt;li&gt;and the exact recognition drills that made unfamiliar problems feel solvable again&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.codeintuition.io/blogs/algorithmic-intuition-dsa" rel="noopener noreferrer"&gt;Full breakdown here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Which technique's features finally clicked for you only after seeing it on a problem the explanations had skipped?&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>leetcode</category>
      <category>career</category>
      <category>codinginterview</category>
    </item>
    <item>
      <title>How to Prove Your Algorithm Works in a Coding Interview</title>
      <dc:creator>Prakhar Srivastava</dc:creator>
      <pubDate>Wed, 06 May 2026 14:00:00 +0000</pubDate>
      <link>https://forem.com/codeintuition/how-to-prove-your-algorithm-works-in-a-coding-interview-38mh</link>
      <guid>https://forem.com/codeintuition/how-to-prove-your-algorithm-works-in-a-coding-interview-38mh</guid>
      <description>&lt;p&gt;An interviewer asks you to convince them your algorithm works. You walk through &lt;code&gt;[2, 1, 5, 1, 3, 2]&lt;/code&gt; with &lt;code&gt;K=3&lt;/code&gt;, get &lt;code&gt;9&lt;/code&gt;, and stop. The interviewer waits. You realise that what you did was test one input, not prove correctness, and you don't have anything else to say.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Proving your algorithm works in interviews isn't a formal induction. It's two things: state what property your loop maintains at each step (the invariant), then check initialization, termination, and edge cases. Tracing one example is testing, not proving. The invariant is what bridges one input to all of them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What "prove your algorithm is correct" actually means in an interview
&lt;/h2&gt;

&lt;p&gt;If you took a discrete math course, you spent weeks on induction proofs with formal notation. That isn't what an interviewer wants. They want what a senior engineer does in code review: read the loop, ask "what's true at each iteration?", and check whether that property forces the right answer.&lt;/p&gt;

&lt;p&gt;The two are related. They share the invariant idea. But the academic version is a paper proof, and the interview version is a 90 second verbal walkthrough. Mixing them up is why most candidates either freeze or write something that looks like exam notation.&lt;/p&gt;

&lt;p&gt;When the interviewer says "convince me this works," they want three things in order: the property your loop holds, evidence it holds at every step, and a check that the final state gives the right answer. Doing this clearly is rare, and noticeable when you can.&lt;/p&gt;

&lt;h2&gt;
  
  
  The two checks
&lt;/h2&gt;

&lt;p&gt;Two checks carry the whole method.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;State and verify the loop invariant.&lt;/strong&gt; Before tracing any code, write down what's supposed to be true at the start of each iteration. Then trace 3 to 4 iterations, confirming the property after each one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check boundaries and termination.&lt;/strong&gt; The invariant covers the loop body. Boundaries cover what happens before the loop starts, after it ends, and on degenerate inputs (empty array, single element, all identical values, maximum size).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most candidates skip step 1 and jump straight into tracing a specific input. That's testing. Testing tells you it works for &lt;em&gt;that&lt;/em&gt; input. The invariant tells you it works for every input.&lt;/p&gt;

&lt;p&gt;The difference matters when an interviewer asks about an input you didn't trace. "My sliding window maintains the sum of exactly &lt;code&gt;K&lt;/code&gt; elements at each step, and the update adds the new element and subtracts the leaving one" lets the interviewer check the mechanism. "I ran it on &lt;code&gt;[2, 1, 5, 1, 3, 2]&lt;/code&gt; and got 9" leaves them wondering about everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  A worked example: fixed sliding window
&lt;/h2&gt;

&lt;p&gt;Take the classic problem: given an array and a window size &lt;code&gt;K&lt;/code&gt;, find the maximum sum of any contiguous subarray of length &lt;code&gt;K&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;max_sum_subarray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&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="n"&gt;window_sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&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="n"&gt;max_sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;window_sum&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
        &lt;span class="n"&gt;window_sum&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;arr&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;arr&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;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;max_sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;window_sum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;max_sum&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 1: State and verify the invariant
&lt;/h3&gt;

&lt;p&gt;The invariant: at the start of each iteration, &lt;code&gt;window_sum&lt;/code&gt; equals the sum of elements in the current window of &lt;code&gt;K&lt;/code&gt; elements.&lt;/p&gt;

&lt;p&gt;Trace it on &lt;code&gt;arr = [2, 1, 5, 1, 3, 2]&lt;/code&gt; with &lt;code&gt;K = 3&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Before the loop: &lt;code&gt;window_sum = 2 + 1 + 5 = 8&lt;/code&gt;. The window covers indices &lt;code&gt;0..2&lt;/code&gt;. The invariant holds.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;i = 3&lt;/code&gt;: &lt;code&gt;window_sum = 8 + arr[3] - arr[0] = 8 + 1 - 2 = 7&lt;/code&gt;. The window is now &lt;code&gt;[1, 5, 1]&lt;/code&gt;, and &lt;code&gt;1 + 5 + 1 = 7&lt;/code&gt;. Holds.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;i = 4&lt;/code&gt;: &lt;code&gt;window_sum = 7 + arr[4] - arr[1] = 7 + 3 - 1 = 9&lt;/code&gt;. Window is &lt;code&gt;[5, 1, 3]&lt;/code&gt;, sums to 9. Holds.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;i = 5&lt;/code&gt;: &lt;code&gt;window_sum = 9 + arr[5] - arr[2] = 9 + 2 - 5 = 6&lt;/code&gt;. Window is &lt;code&gt;[1, 3, 2]&lt;/code&gt;, sums to 6. Holds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The reason the invariant is &lt;em&gt;maintained&lt;/em&gt; matters more than the trace itself. The update adds the element entering the window and subtracts the one leaving. That's the mechanism, not just the result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Check boundaries and termination
&lt;/h3&gt;

&lt;p&gt;Initialization: the code computes the sum of the first &lt;code&gt;K&lt;/code&gt; elements directly, so the invariant holds before the loop runs.&lt;/p&gt;

&lt;p&gt;Termination: the loop runs from &lt;code&gt;K&lt;/code&gt; to &lt;code&gt;len(arr) - 1&lt;/code&gt;, so the final window covers the last &lt;code&gt;K&lt;/code&gt; elements. &lt;code&gt;max_sum&lt;/code&gt; has tracked the maximum across every window the loop visited.&lt;/p&gt;

&lt;p&gt;Edge cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;K == len(arr)&lt;/code&gt;: the loop body never runs, and the initial &lt;code&gt;window_sum&lt;/code&gt; is already the answer.&lt;/li&gt;
&lt;li&gt;All negative numbers: the invariant doesn't depend on sign, so it still holds.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;K == 1&lt;/code&gt;: each window is one element. The update shifts by one position correctly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's a complete interview-grade correctness argument. You stated what's true at every step, you explained why the update preserves it, and you confirmed the final state gives the right answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where most candidates lose the argument
&lt;/h2&gt;

&lt;p&gt;Five ways correctness reasoning falls apart, all avoidable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;"It works on my example" fallacy.&lt;/strong&gt; Tracing one input is a single data point. You haven't proven anything about the inputs you didn't trace. The invariant is what generalises.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not articulating the invariant.&lt;/strong&gt; You probably have an intuitive sense of what each iteration does. Without putting that into a checkable sentence, the interviewer hears handwaving at the code, not a claim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skipping boundary checks.&lt;/strong&gt; The invariant covers the loop body. It doesn't tell you what happens on an empty array, a single element, or when &lt;code&gt;K&lt;/code&gt; equals the array length. Each of those needs separate verification.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proving termination, not correctness.&lt;/strong&gt; "The loop runs &lt;code&gt;n&lt;/code&gt; times and exits" tells the interviewer the algorithm halts. It says nothing about whether the output is right. Termination and correctness are independent properties.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overcomplicating the argument.&lt;/strong&gt; If your reasoning takes three paragraphs, your algorithm might be too complex. Simpler algorithms have simpler invariants. That's part of why interviewers prefer elegant solutions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Invariants change shape across patterns
&lt;/h2&gt;

&lt;p&gt;The sliding window invariant tracks one running variable. Other patterns produce invariants with different shapes, and recognising those shapes is half of what makes the skill transfer.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Invariant shape&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Sorted two pointers&lt;/td&gt;
&lt;td&gt;The answer, if it exists, lies within &lt;code&gt;[left, right]&lt;/code&gt;. Each step shrinks the search space without skipping a valid pair.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Binary search&lt;/td&gt;
&lt;td&gt;The target, if present, lies within &lt;code&gt;arr[low..high]&lt;/code&gt;. Every iteration halves the range while preserving that guarantee.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BFS on unweighted graph&lt;/td&gt;
&lt;td&gt;When a node is dequeued, its recorded distance equals the shortest path from the source. This depends on FIFO ordering and equal edge weights.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Topological sort via DFS&lt;/td&gt;
&lt;td&gt;A node is added to the result only after all its descendants have been added. Reversing the post-order produces a valid ordering.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0/1 knapsack DP&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;dp[i][w]&lt;/code&gt; equals the maximum value using items &lt;code&gt;0..i&lt;/code&gt; with capacity &lt;code&gt;w&lt;/code&gt;. Each cell depends only on previously computed cells.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The two step structure is the same across all of them. State the property, verify the boundaries. What changes is what the invariant looks like and how many variables it tracks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practising under time pressure
&lt;/h2&gt;

&lt;p&gt;Knowing the method and producing one in 45 minutes are different. The bottleneck isn't understanding what an invariant is. It's stating one quickly for an algorithm you just designed.&lt;/p&gt;

&lt;p&gt;A drill that works: pick a problem you've already solved. Set a timer for 60 seconds. Try to state the loop invariant in one sentence. If you can't, that's a signal you solved the problem by pattern matching, not by understanding what made it work. Re-read the code and figure out what property the algorithm depends on.&lt;/p&gt;

&lt;p&gt;Run that drill on five problems across five different patterns each week. After a month, two things change. First, articulating invariants becomes reflexive. Second, your debugging gets faster, because checking whether the invariant still holds at each step pinpoints the broken iteration faster than tracing the full execution.&lt;/p&gt;

&lt;p&gt;A second drill is wrong invariant spotting. Take a correct algorithm. Write down an invariant that &lt;em&gt;sounds&lt;/em&gt; plausible but is subtly wrong. Find the iteration where it breaks. This trains the gap between invariants that describe what the code does and invariants that guarantee correctness. Most interview mistakes live in that gap.&lt;/p&gt;

&lt;p&gt;I keep watching this play out across engineers I see prep. The ones who can articulate invariants under pressure are usually the ones who solved fewer problems but understood each one more deeply. The ones who froze had solved more but couldn't say what made any single algorithm work.&lt;/p&gt;

&lt;p&gt;If you want a worked walkthrough of why the variable sliding window update preserves the invariant before you ever solve a problem with it, &lt;a href="https://www.codeintuition.io/courses/array/wAvrphLQKKOxZazp-fg6X" rel="noopener noreferrer"&gt;the variable sliding window lesson&lt;/a&gt; walks through it step by step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two halves of the same skill
&lt;/h2&gt;

&lt;p&gt;Correctness reasoning and mental dry running pair together. The dry run gives you the trace. The invariant gives you the claim to verify against the trace. Practising them apart leaves a hole that interview pressure exposes. Practising them together is what makes the reasoning hold up when the algorithm is one you just designed.&lt;/p&gt;

&lt;p&gt;The same idea shows up in dynamic programming. When you derive a recurrence, you're implicitly stating an invariant: &lt;code&gt;dp[i]&lt;/code&gt; represents the optimal answer for the first &lt;code&gt;i&lt;/code&gt; elements. Proving that recurrence correct uses the same two step structure, just with a table-shaped invariant instead of a scalar one.&lt;/p&gt;

&lt;p&gt;If you’ve ever frozen when an interviewer said “prove your algorithm works,” the missing piece usually isn’t more problems.&lt;/p&gt;

&lt;p&gt;It’s learning to articulate the invariant.&lt;/p&gt;

&lt;p&gt;I wrote a &lt;a href="https://www.codeintuition.io/blogs/algorithm-correctness-proof" rel="noopener noreferrer"&gt;longer breakdown&lt;/a&gt; covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;nested loop invariants&lt;/li&gt;
&lt;li&gt;wrong invariant drills&lt;/li&gt;
&lt;li&gt;DP correctness reasoning&lt;/li&gt;
&lt;li&gt;and how to structure interview-grade proofs without formal notation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which algorithm did you finally feel confident in only after you could state its invariant out loud?&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>leetcode</category>
      <category>datastructures</category>
      <category>career</category>
    </item>
    <item>
      <title>AlgoExpert vs NeetCode: The Interview Skill Neither One Actually Trains</title>
      <dc:creator>Prakhar Srivastava</dc:creator>
      <pubDate>Tue, 05 May 2026 22:31:58 +0000</pubDate>
      <link>https://forem.com/codeintuition/algoexpert-vs-neetcode-the-interview-skill-neither-one-actually-trains-567f</link>
      <guid>https://forem.com/codeintuition/algoexpert-vs-neetcode-the-interview-skill-neither-one-actually-trains-567f</guid>
      <description>&lt;p&gt;A few years back I worked through both AlgoExpert and NeetCode while preparing for interviews. The 100 polished videos and the 400+ free walkthroughs were useful for what they covered. The interview round that broke me wasn't a problem either platform had skipped. It was a problem they both had a clean walkthrough for, where I could read either solution after the round and recognise the technique, but in 25 minutes against a whiteboard I couldn't see it.&lt;/p&gt;

&lt;p&gt;The problem was Longest Palindromic Substring. Both platforms have a video. Both derive expand around centre cleanly. After watching either, the technique makes sense. The issue was the interviewer didn't say "this is a palindrome expansion problem." The prompt said "find the longest substring that reads the same forwards and backwards." That gap, between the technique I could follow on a video and the technique I could spot from a description, is what neither platform set out to train.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; AlgoExpert wins on video depth per problem. NeetCode wins on breadth and free access. Both teach how techniques work after you've named the technique. Neither teaches the recognition before the technique gets named, and that recognition is what an unseen medium problem tests.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What AlgoExpert is good at
&lt;/h2&gt;

&lt;p&gt;Clement's videos are clean. There's no other word for them. He picks 100 problems, records each one, walks brute force to optimal in a consistent visual style, and the editing makes the reasoning easy to follow. The single instructor consistency is underrated. After three videos you've adapted to his vocabulary, his pacing, and his shorthand for tradeoffs. From video four onward you spend less time adapting and more time absorbing.&lt;/p&gt;

&lt;p&gt;The browser IDE inside AlgoExpert is also the best of any platform I tried that leads with video. After watching the walkthrough you have a workspace already loaded with the function signature, the tests, and the language template. The transition from passive watching to active solving costs you no setup, which matters more than it sounds.&lt;/p&gt;

&lt;p&gt;The bundle is the other thing the platform gets right. SystemsExpert and FrontendExpert sit beside AlgoExpert under one account. If you're prepping across DSA, system design, and frontend rounds, paying once for three coordinated curriculums is a real saving in cognitive load alone. The argument that "100 problems is too few" misses what AlgoExpert is going for. The platform aims for depth on a small set, not coverage of everything. On that goal it lands.&lt;/p&gt;

&lt;h2&gt;
  
  
  What NeetCode does well
&lt;/h2&gt;

&lt;p&gt;NeetCode's free tier is the best reason to start there. The YouTube channel covers more problems than most paid platforms, and the production quality has improved year over year. NeetCode 150 is the most widely shared curated list in the prep community for a reason. You get a defensible problem ordering without any commitment.&lt;/p&gt;

&lt;p&gt;The community momentum is the second thing NeetCode does that almost nobody else matches. Engineers swap solutions in the YouTube comments, swap timelines on the subreddit, swap notes in Discord. Studying alone is the failure mode for most preparation. A platform that pulls you into a group of people preparing in parallel is doing real work, even if the work isn't a feature on a comparison sheet.&lt;/p&gt;

&lt;p&gt;The mapping to LeetCode is also worth naming. The problems you practise on NeetCode are the same problems Big Tech screening tools serve, which means your practice environment matches your screening environment. AlgoExpert's IDE is more polished, but NeetCode's environment matches what you'll actually face when a recruiter sends you a Codility or HackerRank link.&lt;/p&gt;

&lt;h2&gt;
  
  
  The shared gap, made concrete
&lt;/h2&gt;

&lt;p&gt;Take Longest Palindromic Substring. The interview prompt is one sentence: given a string, return the longest substring that reads the same forwards and backwards. AlgoExpert's video derives expand around centre cleanly. NeetCode's video does the same with a slightly different style. Watch either and the solution makes sense.&lt;/p&gt;

&lt;p&gt;What neither video sets you up to do is the move that happens before the technique gets named. The move is reading the prompt, noticing that a substring is being asked for, noticing the symmetry constraint, and reaching for expand around centre rather than DP because of those two visible features. In an interview, no one labels the problem for you. Your search for a technique starts from the description, not from a category tag.&lt;/p&gt;

&lt;p&gt;The pattern repeats across topics. Take a tree problem like Binary Tree Maximum Path Sum. Both platforms have walkthroughs. After watching either you can reproduce the postorder helper that returns the local max while updating a global. What neither walkthrough installs is the recognition that "any node, any path, any direction" signals the helper-with-side-effects pattern. The walkthrough teaches the pattern. The recognition is a separate skill the walkthrough assumes you'll pick up by exposure.&lt;/p&gt;

&lt;h2&gt;
  
  
  What recognition is, mechanically
&lt;/h2&gt;

&lt;p&gt;Recognition is a small set of features you can name on the prompt before any code is written. For expand around centre, the features are roughly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The output is a substring of a string.&lt;/li&gt;
&lt;li&gt;The constraint involves symmetry, palindromes, or some "reads the same in both directions" property.&lt;/li&gt;
&lt;li&gt;Other approaches bottom out at quadratic, so the technique you're looking for is &lt;code&gt;O(n^2)&lt;/code&gt; or &lt;code&gt;O(n log n)&lt;/code&gt;, not &lt;code&gt;O(n)&lt;/code&gt; or sub-linear.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When all three apply, expand around centre is the candidate technique to try. Longest Palindromic Substring matches all three. Palindromic Substrings (count, not length) matches the first two. Both fall under the same recognition rule.&lt;/p&gt;

&lt;p&gt;This is the part neither AlgoExpert nor NeetCode targets directly. Their walkthroughs assume you've already arrived at the technique, then explain it. The arriving is the work no one is helping you do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why volume alone doesn't close it
&lt;/h2&gt;

&lt;p&gt;The cognitive science name for this is the &lt;a href="https://en.wikipedia.org/wiki/Generation_effect" rel="noopener noreferrer"&gt;generation effect&lt;/a&gt;. Producing an answer from first principles, even imperfectly, builds stronger memory and stronger transfer than recognising a familiar solution. Watching a walkthrough builds recognition of an answer you've been shown. Interviews ask for generation, where you produce the technique from a description you haven't seen.&lt;/p&gt;

&lt;p&gt;What you watch and what you generate aren't the same skill. Watching ten variants of expand around centre gives you a strong recognition memory for variants close to what you watched. The interview problem is rarely close enough. It tends to look just different enough that the recognition memory misses, and you stall on what to try next.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://en.wikipedia.org/wiki/Transfer_of_learning" rel="noopener noreferrer"&gt;transfer of learning&lt;/a&gt; literature splits this into near transfer and far transfer. Near transfer is solving problems that look like ones you've already solved. Far transfer is reasoning through problems that look different but follow the same underlying pattern. Volume in the AlgoExpert / NeetCode mode produces near transfer reliably. Far transfer comes from a different practice shape, where the recognition gets trained on its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  A recognition protocol you can run this week
&lt;/h2&gt;

&lt;p&gt;If you've worked through either platform's content and unfamiliar mediums still freeze you, the move isn't another fifty walkthroughs. It's a tighter loop on recognition first.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pick one technique a week. Expand around centre, sliding window, two pointer, monotonic stack, postorder with side effects.&lt;/li&gt;
&lt;li&gt;Write down the trigger features for that technique. Three or four specific features you can see in a problem statement that, when they all apply, make this technique the candidate. Write them in your own words, not from a cheat sheet.&lt;/li&gt;
&lt;li&gt;Read five problems that use this technique without solving them. For each, name the triggers you can see in the prompt before reading any constraints in detail.&lt;/li&gt;
&lt;li&gt;Solve three or four problems on the technique with the problem name and category tag hidden. The cover-the-name move is what forces you to recognise the technique before coding starts.&lt;/li&gt;
&lt;li&gt;Once a week, do one pressure session. Cover the title, set 25 minutes, talk through your reasoning out loud, and don't open the IDE until you've named the technique you intend to use.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A technique a week, eight or ten weeks of focused work. That replaces the hundred-plus mediums where the signal you actually need gets buried under details that don't matter.&lt;/p&gt;

&lt;p&gt;Both AlgoExpert and NeetCode are reasonable choices for the watching part of this loop. Once you've watched the technique once or twice, the work that compounds is the recognition reps the walkthroughs don't include.&lt;/p&gt;

&lt;p&gt;If you’ve already watched hundreds of walkthroughs but still freeze on unfamiliar mediums, the problem usually isn’t knowledge.&lt;/p&gt;

&lt;p&gt;It’s recognition.&lt;/p&gt;

&lt;p&gt;I wrote a &lt;a href="https://www.codeintuition.io/blogs/algoexpert-vs-neetcode" rel="noopener noreferrer"&gt;longer breakdown&lt;/a&gt; comparing AlgoExpert and NeetCode on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;depth vs breadth&lt;/li&gt;
&lt;li&gt;passive watching vs active recall&lt;/li&gt;
&lt;li&gt;and the recognition drills that finally fixed this for me&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When did the recognition click for a pattern you used to watch and re-watch without spotting on a fresh problem, and what was the specific problem that broke it open?&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>career</category>
      <category>leetcode</category>
      <category>learning</category>
    </item>
    <item>
      <title>The 90 Day FAANG Prep Plan That Actually Works</title>
      <dc:creator>Prakhar Srivastava</dc:creator>
      <pubDate>Mon, 04 May 2026 20:30:50 +0000</pubDate>
      <link>https://forem.com/codeintuition/the-90-day-faang-prep-plan-that-actually-works-stop-studying-in-the-wrong-order-4he7</link>
      <guid>https://forem.com/codeintuition/the-90-day-faang-prep-plan-that-actually-works-stop-studying-in-the-wrong-order-4he7</guid>
      <description>&lt;p&gt;You count the weeks between today and your on site. Twelve. You pull up a 90 day FAANG prep plan and the structure looks reasonable: easy problems for two weeks, mediums for six, hards for the rest. Six weeks in, you hit binary trees and realise your recursion is shaky. Two weeks later you try a DP problem and can't formulate the recurrence. Suddenly the 12 week plan is a 6 week plan with 6 weeks of rework.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Difficulty isn’t the problem. Order is.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; A 90 day FAANG plan works when topics are ordered by dependency, not by difficulty or popularity. The typical "easy then medium then hard" plan ignores that DP needs recursion, recursion needs the call stack, and the call stack needs array fundamentals. Sequence by what each topic &lt;em&gt;requires&lt;/em&gt;, not by how hard it feels.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What "wrong order" actually looks like
&lt;/h2&gt;

&lt;p&gt;The failure mode in most 90 day plans is the same shape every time. The plan groups topics by surface difficulty: arrays first because they are easy, DP last because it is hard. Or the plan groups by frequency: arrays first because they appear most, then strings, then trees, then DP. Both shapes ignore that DSA topics have hard prerequisites.&lt;/p&gt;

&lt;p&gt;You can't reason about binary tree traversal without recursion. You can't build recursive intuition without the call stack. You can't pattern-match on hash table problems until you have internalised what &lt;code&gt;O(1)&lt;/code&gt; amortised lookup actually buys you. These gaps don't show up in Week 2. They show up around Week 5 or Week 7, deep enough into the plan that you've already built a lot on top of unstable ground.&lt;/p&gt;

&lt;p&gt;When that happens, the plan quietly stops working. You either skip the prerequisite to "stay on schedule," which compounds the gap into every later topic, or you stop and rebuild, which eats two of the remaining weeks. Either way, the timeline collapses.&lt;/p&gt;

&lt;h2&gt;
  
  
  The order that actually works
&lt;/h2&gt;

&lt;p&gt;Here's the dependency order that emerges after watching dozens of engineers prep:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Weeks 1 to 2: Arrays and linked lists.&lt;/strong&gt; Two pointers, sliding window, interval merging on arrays. Reversal, fast and slow pointers, merge patterns on linked lists. About fifteen patterns. Everything else builds on these.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weeks 3 to 4: Hash tables and stacks.&lt;/strong&gt; Hash tables unlock counting, prefix sum, and the harder variants of sliding window. Stacks unlock monotonic stack, sequence validation, expression evaluation. Both are prerequisites for tree traversal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weeks 5 to 6: Queues, binary trees, BSTs.&lt;/strong&gt; Queues for level order BFS. Trees for preorder, postorder, root to leaf paths. BSTs for sorted traversal and range operations. Pattern density picks up fast here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weeks 7 to 8: Heaps, recursion, backtracking.&lt;/strong&gt; Heaps for top K and comparator patterns. Recursion formalises head recursion, tail recursion, and multiple recursion. Backtracking introduces enumeration and constraint search.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weeks 9 to 10: Graphs, sorting, searching.&lt;/strong&gt; DFS, BFS, Dijkstra, topological sort. Quickselect and custom compare. Binary search variants including predicate search on the answer space.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weeks 11 to 12: Dynamic programming and review.&lt;/strong&gt; DP last, because DP is what every previous topic was preparing you for.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Wikipedia article on the &lt;a href="https://en.wikipedia.org/wiki/Spacing_effect" rel="noopener noreferrer"&gt;spacing effect&lt;/a&gt; summarises why this order also helps retention: practice distributed across weeks, with each week building on the last, produces stronger durable recall than the same volume crammed late. The dependency order isn't only logical, it's also how you keep the early weeks from fading by Week 12.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why DP belongs at Week 11, not Week 3
&lt;/h2&gt;

&lt;p&gt;Take Coin Change, a standard DP interview problem. To derive the solution rather than memorise it, you need three things lined up:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A recurrence relation. Built on top of recursion fluency.&lt;/li&gt;
&lt;li&gt;Recognition of overlapping subproblems. Built on top of seeing how multiple recursive calls share state.&lt;/li&gt;
&lt;li&gt;Memoization. Built on top of understanding how cached results map to subproblem states.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now imagine an engineer who reaches DP in Week 3. They've covered arrays, maybe linked lists. They have not internalised the call stack, they have not seen recursion expressed as a recurrence, they have not seen overlapping subproblems show up anywhere. The Coin Change solution they study isn't reasoning, it's a string of four lines they're supposed to remember:&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;def&lt;/span&gt; &lt;span class="nf"&gt;coinChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;coins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;dp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;inf&lt;/span&gt;&lt;span class="sh"&gt;'&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="n"&gt;amount&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;dp&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&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="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;coins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;c&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="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;dp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;inf&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The engineer who reaches the same problem in Week 11 sees this differently. They've spent four weeks with recursion. They've built backtracking on top of multiple-call recursion. They've seen the same &lt;code&gt;dp[i]&lt;/code&gt; shape applied to climbing stairs, then to longest increasing subsequence, then to Coin Change. The recurrence &lt;code&gt;dp[a] = min(dp[a], dp[a - c] + 1)&lt;/code&gt; doesn't have to be remembered, because they can re-derive it from the invariant: &lt;code&gt;dp[a]&lt;/code&gt; is the minimum number of coins to make amount &lt;code&gt;a&lt;/code&gt;, and the only way to make &lt;code&gt;a&lt;/code&gt; is to make &lt;code&gt;a - c&lt;/code&gt; for some coin &lt;code&gt;c&lt;/code&gt; and add one.&lt;/p&gt;

&lt;p&gt;That's the difference dependency order produces. Not more knowledge. Knowledge that holds together under interview pressure because every piece supports the one above it.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to add timed pressure (load-bearing)
&lt;/h2&gt;

&lt;p&gt;It is easy to practise in comfort conditions for eleven weeks and then panic in your first mock interview. The gap between "I solved this at my desk with no timer" and "I solved this in 20 minutes with no hints" is wider than most engineers expect. The right time to introduce timed practice is after the foundations are solid but before the advanced topics start. Around Week 6.&lt;/p&gt;

&lt;p&gt;By Week 6, you've covered arrays, linked lists, hash tables, stacks, queues, and started binary trees. That's enough pattern coverage to attempt timed problems honestly. You won't know every pattern yet, but you know enough to practise the skill of solving under pressure separately from the skill of learning new patterns.&lt;/p&gt;

&lt;p&gt;From Week 6 to Week 8, attempt previously completed problems under a timer. Twenty minutes for mediums, thirty for hards. No hints, no notes. The goal isn't a clean pass rate, it's training the feeling of working without the safety of references while the material is still fresh in your mind.&lt;/p&gt;

&lt;p&gt;From Week 9 to Week 12, switch to multi problem assessments under a 50 minute timer, the way actual rounds work. You'll have covered enough of the patterns by then to simulate realistic interview coverage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Productive struggle vs spinning
&lt;/h2&gt;

&lt;p&gt;Plans break. You'll have a week where work blows up, or you'll hit a topic that takes longer than expected. The better question isn't "how do I avoid falling behind," it's "how do I tell whether I'm stuck productively or just spinning."&lt;/p&gt;

&lt;p&gt;The two look similar from the inside but feel different in one specific way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Productive struggle.&lt;/strong&gt; You can name what you don't understand. "Merge sort is &lt;code&gt;O(n log n)&lt;/code&gt;, but the reason the divide step doesn't add extra cost isn't clicking." That's a specific gap you can target with a specific lesson, problem, or question.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spinning.&lt;/strong&gt; You're re-reading the same material without forming new questions. You've watched the same walkthrough three times and still can't reproduce the logic from a blank screen.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're spinning, change the input. Try solving a strictly simpler variant. Try writing the solution from memory without any reference, even if you produce something wrong. Try explaining the concept out loud as if to a junior. The act of generating an attempt, even a broken one, surfaces the missing piece more clearly than another round of passive review. This is the &lt;a href="https://en.wikipedia.org/wiki/Generation_effect" rel="noopener noreferrer"&gt;generation effect&lt;/a&gt; doing real work for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concrete checkpoints (because vague progress isn't progress)
&lt;/h2&gt;

&lt;p&gt;Vague progress signals like "things are starting to click" don't survive interview-week stress. Use concrete checkpoints at each month boundary. If three or more items at any checkpoint don't describe you, don't move to the next month. Spend an extra week on the weak areas. A 13 week plan that's solid beats a 12 week plan with holes.&lt;/p&gt;

&lt;p&gt;By Week 4, you should be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Solve array two pointer and sliding window problems without looking up the pattern.&lt;/li&gt;
&lt;li&gt;Trace linked list reversal mentally, tracking pointer state at each step.&lt;/li&gt;
&lt;li&gt;Explain &lt;em&gt;why&lt;/em&gt; a hash table lookup is &lt;code&gt;O(1)&lt;/code&gt; amortised, not just that it is.&lt;/li&gt;
&lt;li&gt;Identify which stack pattern applies from the problem statement alone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By Week 8:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trace a binary tree postorder traversal on paper, tracking state at each node.&lt;/li&gt;
&lt;li&gt;Reason about BST problems through the sorted traversal invariant.&lt;/li&gt;
&lt;li&gt;Write a recursive solution and walk through how the call stack unwinds.&lt;/li&gt;
&lt;li&gt;Have attempted ten or more problems under timed conditions, with a pass rate above 50%.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By Week 12:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify DP subproblems and formulate recurrences for problems you haven't seen.&lt;/li&gt;
&lt;li&gt;Choose between BFS and DFS for a graph problem and explain why.&lt;/li&gt;
&lt;li&gt;Complete a 50 minute multi problem assessment with at least one correct solution.&lt;/li&gt;
&lt;li&gt;Hit the timer without reaching for the solution tab first.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you can't honestly check most of these, your plan needs an extra week, not a heroic weekend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your final week
&lt;/h2&gt;

&lt;p&gt;Week 12 isn't for new material. If you're still covering fresh topics with seven days to go, something earlier broke. The final week is for consolidation under realistic conditions.&lt;/p&gt;

&lt;p&gt;Days 1 to 3 are targeted weak spot practice. Look back at the timed results from Weeks 9 to 11. Which topics had the lowest pass rate? Which patterns did you fail to identify within the first five minutes? Spend three days isolating those specific patterns and attempting two or three problems that test exactly that pattern. Don't re-study the entire topic. Isolate the gap.&lt;/p&gt;

&lt;p&gt;Days 4 to 5 are full simulation rounds. Two complete mock interview simulations. Forty five to fifty minutes, two problems, no IDE autocompletion, talk out loud as you write. If you don't have a partner, record yourself. The recording forces the same "someone is watching" pressure that slows people down in real interviews. Pay attention to time allocation. The most common failure pattern is spending thirty minutes on the first problem and having fifteen for the second. Practise the discipline of checking your progress at the 20 minute mark and making a deliberate decision about whether to keep debugging or move on.&lt;/p&gt;

&lt;p&gt;Days 6 to 7 are rest and review. Stop solving new problems. Review your notes on the three or four patterns you found hardest. Get enough sleep. The difference between a well rested engineer who's covered 90% of the material and an exhausted engineer who's crammed 100% is measurable in interview performance. Fatigue degrades pattern recognition speed before it degrades anything else, and recognition speed is exactly what interviews test.&lt;/p&gt;

&lt;h2&gt;
  
  
  The order is the advantage
&lt;/h2&gt;

&lt;p&gt;Compressing the whole roadmap into one rule: study what each topic requires, not what feels hardest. The Coin Change recurrence at Week 11 holds together because every layer below it (recursion in Week 7, stack mechanics in Week 4, array fundamentals in Week 1) was built before it was needed. An engineer who jumps to DP in Week 3 isn't ahead, they're standing on nothing.&lt;/p&gt;




&lt;p&gt;If you want the full version of this roadmap with exact problem lists, pattern breakdowns, and weekly schedules I’ve written it &lt;a href="https://www.codeintuition.io/blogs/90-day-faang-preparation" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;This post gives you the structure.&lt;br&gt;&lt;br&gt;
The full guide gives you the execution.&lt;/p&gt;




&lt;p&gt;What’s the topic in your prep where the dependency chain finally clicked—and which week did it happen?&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>career</category>
      <category>learning</category>
      <category>faang</category>
    </item>
    <item>
      <title>I Solved 200 LeetCode Problems and Still Froze in Interviews</title>
      <dc:creator>Prakhar Srivastava</dc:creator>
      <pubDate>Sun, 03 May 2026 16:27:58 +0000</pubDate>
      <link>https://forem.com/codeintuition/i-solved-200-leetcode-problems-and-still-froze-in-interviews-1hoj</link>
      <guid>https://forem.com/codeintuition/i-solved-200-leetcode-problems-and-still-froze-in-interviews-1hoj</guid>
      <description>&lt;p&gt;A few years ago I solved 200 LeetCode problems and still froze on Mediums I hadn't seen. The breakthrough wasn't another hundred problems. It was a different loop.&lt;/p&gt;

&lt;p&gt;A problem asks for the longest substring with at most K distinct characters. You've solved sliding window before. Maximum sum subarray of size K, done. Longest substring without repeating characters, done. This third one stalls you. Twenty minutes pass. Discuss says sliding window. You'd already solved sliding window problems. The recognition didn't work on this one.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; Practice volume builds memory of specific problems, not the recognition you have to do before you start coding. The skill that transfers to unfamiliar interview mediums is identifying which technique applies from what the problem looks like. That recognition is what most LeetCode-style prep doesn't train, and that gap is what this post is about.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What LeetCode actually does well
&lt;/h2&gt;

&lt;p&gt;LeetCode is the default coding interview prep platform for a reason. The problem bank is the strongest available: 3,000+ problems across every common data structure, tagged by company and frequency. The company tagging is the most reliable public signal you can get for "what does Amazon currently ask." Nothing else is close on that dimension.&lt;/p&gt;

&lt;p&gt;The free tier is generous, the discuss forum is open, and the weekly contests are free. If you already understand the underlying patterns and you need volume to drill them, LeetCode is the right platform. The contest system is genuinely underrated for building speed under time. Top voted discuss replies on popular problems also hold up. They often explain the reasoning more clearly than the official editorials.&lt;/p&gt;

&lt;p&gt;So the question isn't whether LeetCode is good. It is good. The real question is whether the thing holding you back is the kind of thing LeetCode's design actually fixes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The gap volume doesn't close
&lt;/h2&gt;

&lt;p&gt;The earlier sliding window problems taught implementation on those specific problems, not the rule for when sliding window applies. The connection between "K distinct characters" and "variable sliding window" was never made explicit anywhere in your prep. You learned an implementation by example, not a recognition rule. When the visible parts of the problem change, the implementation memory doesn't carry over.&lt;/p&gt;

&lt;p&gt;Learning research calls this near transfer versus far transfer. Near transfer means solving problems that look like ones you've already solved. Far transfer means reasoning through problems that look different but follow the same underlying pattern. The Wikipedia article on &lt;a href="https://en.wikipedia.org/wiki/Transfer_of_learning" rel="noopener noreferrer"&gt;transfer of learning&lt;/a&gt; covers it. The short version: practice volume produces near transfer reliably and far transfer unreliably. You can grind 500 problems and still not generalise across the differences in description if no one ever taught you which features signal which pattern.&lt;/p&gt;

&lt;p&gt;That isn't a talent gap. It's a gap in the method.&lt;/p&gt;

&lt;h2&gt;
  
  
  What recognition actually looks like
&lt;/h2&gt;

&lt;p&gt;Recognition is reading a problem statement, naming the visible features, and matching them to a technique before any code is written. Every technique has a small set of trigger conditions, usually three to five. When all of them match, you've identified the technique.&lt;/p&gt;

&lt;p&gt;For variable sliding window, the trigger conditions are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The input is a contiguous range (a substring, a subarray, a window of consecutive elements).&lt;/li&gt;
&lt;li&gt;The optimisation target is the length of that range (longest, shortest, smallest valid).&lt;/li&gt;
&lt;li&gt;There is a condition you can check incrementally as the window expands or contracts (count of distinct characters, sum within bounds, set membership).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When all three apply, variable sliding window is the technique. K distinct characters hits all three. So does longest substring without repeating characters. So does minimum window substring. The triggers are the same. The descriptions differ.&lt;/p&gt;

&lt;p&gt;The skill is matching problems to triggers before coding. That's what doesn't get built by grinding problems sequentially.&lt;/p&gt;

&lt;h2&gt;
  
  
  A code template you can adapt
&lt;/h2&gt;

&lt;p&gt;Here's the variable sliding window template in Python. Once you recognise the technique, the implementation has very few moving parts.&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;def&lt;/span&gt; &lt;span class="nf"&gt;variable_window&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;init_state&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;best&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;right&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
        &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;expand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;shrink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;left&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
        &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;best&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For K distinct characters, &lt;code&gt;state&lt;/code&gt; is a hash map of character counts within the current window, &lt;code&gt;condition&lt;/code&gt; is &lt;code&gt;len(state) &amp;lt;= K&lt;/code&gt;, and &lt;code&gt;shrink&lt;/code&gt; decrements counts and removes keys whose count drops to zero. The recognition step (this is variable sliding window) is the decision that matters. The code follows.&lt;/p&gt;

&lt;p&gt;For longest substring without repeating characters, &lt;code&gt;state&lt;/code&gt; becomes a hash set and &lt;code&gt;condition&lt;/code&gt; is "no duplicate." Same skeleton. Same invariant.&lt;/p&gt;

&lt;p&gt;That's the payoff of recognition trained explicitly. Write the template once. Adapt per problem in two or three lines. Stop staring at problems hoping the right approach surfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  How practice and interview conditions diverge
&lt;/h2&gt;

&lt;p&gt;Recognition is half the gap. The other half is the conditions you practise under. LeetCode's practice environment shows you the problem name (which often hints at the technique), gives unlimited code executions, and doesn't penalise failed attempts. Real interviews give none of that.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Practice (LeetCode default)&lt;/th&gt;
&lt;th&gt;Real interview&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Problem name&lt;/td&gt;
&lt;td&gt;Visible, often hints at category&lt;/td&gt;
&lt;td&gt;Not given&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code executions&lt;/td&gt;
&lt;td&gt;Unlimited, no penalty&lt;/td&gt;
&lt;td&gt;Limited, every failure costs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hints / discuss&lt;/td&gt;
&lt;td&gt;One click away&lt;/td&gt;
&lt;td&gt;Not available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time limit&lt;/td&gt;
&lt;td&gt;Self set, often skipped&lt;/td&gt;
&lt;td&gt;20 to 45 minutes hard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reasoning&lt;/td&gt;
&lt;td&gt;Internal&lt;/td&gt;
&lt;td&gt;Spoken aloud&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The middle column is fine for the early learning phase. Open exploration helps when you're still building the model. The problem comes when those conditions are the only conditions you ever rehearse under, and the actual test wants something the rehearsal never asked for.&lt;/p&gt;

&lt;p&gt;Replicating interview pressure on your own takes one friend and a kitchen timer. The friend covers the problem name and reads the constraints aloud. You set the timer to 20 or 30 minutes. You don't open the IDE before stating the technique you intend to use. Two sessions a week against a friend who isn't shy about silence will do more for interview readiness than another fifty problems on the comfort setting.&lt;/p&gt;

&lt;h2&gt;
  
  
  A protocol you can run this week
&lt;/h2&gt;

&lt;p&gt;If the K distinct characters story sounded like your last three failed problems, the move isn't more volume. It's a tighter loop on recognition first.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pick one technique a week (variable sliding window, two pointers, prefix sum, monotonic stack, and so on).&lt;/li&gt;
&lt;li&gt;Write down the trigger conditions for that technique. Three to five features of the problem that, when they all apply, make this technique the right tool. Write them in your own words, not from a cheat sheet.&lt;/li&gt;
&lt;li&gt;Read five problems that use this technique without solving them. For each, name the triggers you can see in the problem statement before reading the constraints in detail.&lt;/li&gt;
&lt;li&gt;Solve three to five problems on this technique with the problem name and tag hidden. Force the recognition step.&lt;/li&gt;
&lt;li&gt;Once a week, do one timed pressure session: friend covers the title, you talk through your reasoning, no IDE until you've named the technique. If you can't name it inside five minutes, the problem rewinds to the recognition queue, not the implementation queue.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A pattern a week, eight to ten patterns covered, roughly ten weeks of focused work. That replaces the hundreds of mediums where the signal gets buried under details that don't matter.&lt;/p&gt;

&lt;p&gt;The longer write up of this is on &lt;a href="https://www.codeintuition.io/blogs/codeintuition-vs-leetcode" rel="noopener noreferrer"&gt;my own blog&lt;/a&gt;, with trigger conditions for prefix sum, two pointers, and monotonic stack alongside the variable sliding window walkthrough above, plus a worked example on minimum window substring that uses the same template.&lt;/p&gt;

&lt;p&gt;When did the recognition click for a pattern you used to grind without seeing, and what was the specific problem that broke it open?&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I built Codeintuition, a structured learning platform for coding interviews. The post above is about the technique, not the platform.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>leetcode</category>
      <category>career</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
