Day 29: Mock Interview Day
DAY 29 / 30 · WEEK 4
Goal of the day
Section titled “Goal of the day”- Practice under real time pressure — 4 problems, each with a countdown timer, simulating the clock of an actual interview instead of the untimed comfort of a normal practice session.
- Rehearse the discipline from Day 28: state the brute force and its complexity out loud first, name the pattern you’re reaching for and why, then write code.
- Compare your attempt against a full solution and walkthrough for each problem, honestly — the timer is a practice tool, not a pass/fail gate.
Concept
Section titled “Concept”Every pattern in this course has been taught untimed, one at a time, with the day’s title already telling you the answer. A real interview gives you none of that — a problem, a blank editor, and a clock that’s usually somewhere between 20 and 45 minutes for a single question, onsite rounds sometimes tighter. The skill this builds isn’t new algorithm knowledge; it’s calibrating how much time each phase of solving actually takes when someone is watching and the clock is real.
Use each timer exactly like a real interview: press Start, then say your plan out loud (even alone, actually say it) before typing anything. If the buzzer hits zero before you’re done, that’s useful data, not a failure — note which phase ate the time (usually either clarifying too long, or debugging code that skipped the “trace it by hand first” step) and keep going anyway. The full solution and walkthrough are available any time via the reveal buttons, timer running or not.
Diagram: how to spend a 25-minute clock
Section titled “Diagram: how to spend a 25-minute clock”4 timed mock-interview problems
Section titled “4 timed mock-interview problems”Press Start, then work the problem for real before revealing anything. All 4 are Medium — the typical difficulty of a real onsite round.
1. Longest Palindromic Substring
Section titled “1. Longest Palindromic Substring”Medium — LeetCode: Longest Palindromic Substring
Given a string, return its longest palindromic substring. Suggested time: 20 minutes.
Hint: Every palindrome has a center — either a single character (odd length) or a gap between two characters (even length). Try every possible center and expand outward while both sides match. O(n) centers, O(n) expansion each, O(n²) total — no DP table needed.
Solution:
function longestPalindrome(s) { if (s.length < 2) return s; let start = 0, maxLen = 1;
function expand(l, r) { while (l >= 0 && r < s.length && s[l] === s[r]) { l--; r++; } return [l + 1, r - 1]; // the last valid palindrome bounds }
for (let i = 0; i < s.length; i++) { const [l1, r1] = expand(i, i); // odd-length center at i if (r1 - l1 + 1 > maxLen) { start = l1; maxLen = r1 - l1 + 1; } const [l2, r2] = expand(i, i + 1); // even-length center between i and i+1 if (r2 - l2 + 1 > maxLen) { start = l2; maxLen = r2 - l2 + 1; } } return s.substring(start, start + maxLen);}Walkthrough: every index is tried as both an odd-length center (single character) and an even-length center (gap between two characters) — that covers every possible palindrome shape. expand grows outward while the characters on both sides keep matching, and returns the bounds of the last valid match. Whichever expansion produces a longer palindrome than anything seen so far updates start/maxLen. Time O(n²) (n centers, up to O(n) expansion each), space O(1) beyond the output.
2. Merge Intervals
Section titled “2. Merge Intervals”Medium — LeetCode: Merge Intervals
Given a list of intervals, merge all overlapping intervals and return the merged list. Suggested time: 20 minutes.
Hint: Sort by start time first — same opening move as Day 27’s interval greedy, just sorted by the other endpoint. Then walk left to right: if the current interval’s start is within the last merged interval’s end, extend that interval’s end instead of starting a new one.
Solution:
function mergeIntervals(intervals) { if (intervals.length === 0) return []; const sorted = intervals.slice().sort((a, b) => a[0] - b[0]); const result = [sorted[0].slice()];
for (let i = 1; i < sorted.length; i++) { const last = result[result.length - 1]; const [start, end] = sorted[i]; if (start <= last[1]) { last[1] = Math.max(last[1], end); // overlaps — extend the last merged interval } else { result.push([start, end]); // no overlap — starts a new merged interval } } return result;}Walkthrough: sorting by start time means every interval that could possibly overlap the one currently being built is guaranteed to be checked before we move past it. start <= last[1] is the overlap test — note it’s <=, not <, since touching intervals like [1,4] and [4,5] should still merge into [1,5]. Time O(n log n), dominated by the sort; space O(n) for the output.
3. Rotting Oranges
Section titled “3. Rotting Oranges”Medium — LeetCode: Rotting Oranges
Given a grid where each cell is empty (0), a fresh orange (1), or a rotten orange (2), and every minute a rotten orange rots its fresh orange neighbors, return the minimum minutes until no fresh orange remains, or -1 if that’s impossible. Suggested time: 20 minutes.
Hint: Every rotten orange rots its neighbors simultaneously, every minute — that’s multi-source BFS, exactly like Day 24’s 01 Matrix, except the queue seeds with every ALREADY-rotten cell instead of every 0-cell. Track elapsed minutes per queue entry, and count remaining fresh oranges to know if any are unreachable.
Solution:
function orangesRotting(grid) { const rows = grid.length, cols = grid[0].length; const queue = []; let fresh = 0;
for (let r = 0; r < rows; r++) { for (let c = 0; c < cols; c++) { if (grid[r][c] === 2) queue.push([r, c, 0]); // seed with EVERY already-rotten cell else if (grid[r][c] === 1) fresh++; } }
const dirs = [[1, 0], [-1, 0], [0, 1], [0, -1]]; let minutes = 0; let qi = 0; while (qi < queue.length) { const [r, c, t] = queue[qi++]; minutes = Math.max(minutes, t); for (const [dr, dc] of dirs) { const nr = r + dr, nc = c + dc; if (nr >= 0 && nr < rows && nc >= 0 && nc < cols && grid[nr][nc] === 1) { grid[nr][nc] = 2; fresh--; queue.push([nr, nc, t + 1]); } } } return fresh === 0 ? minutes : -1;}Walkthrough: seeding the queue with every rotten cell at once (not just one) is what makes this multi-source BFS — the same trick Day 24’s 01 Matrix used for “distance to nearest 0-cell.” Every cell’s t is exactly how many minutes it took to rot, so the answer is the largest t reached. Any fresh orange never visited means it was unreachable — the fresh counter catches that and returns -1 instead of a wrong number. Time O(rows × cols), space O(rows × cols) for the queue in the worst case.
4. Longest Common Subsequence
Section titled “4. Longest Common Subsequence”Medium — LeetCode: Longest Common Subsequence
Given two strings, return the length of their longest common subsequence (not necessarily contiguous in either string, but in the same relative order in both). Suggested time: 25 minutes — the first 2D DP table in the course, budget extra time to set up the grid correctly.
Hint: Build a 2D table where dp[i][j] is the LCS length using the first i characters of text1 and the first j characters of text2. If those two characters match, extend the diagonal (dp[i-1][j-1] + 1); if they don’t, take the best of dropping one character from either string (max(dp[i-1][j], dp[i][j-1])).
Solution:
function longestCommonSubsequence(text1, text2) { const m = text1.length, n = text2.length; const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
for (let i = 1; i <= m; i++) { for (let j = 1; j <= n; j++) { if (text1[i - 1] === text2[j - 1]) { dp[i][j] = dp[i - 1][j - 1] + 1; // characters match — extend the diagonal } else { dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]); // no match — best of dropping either side } } } return dp[m][n];}Walkthrough: row 0 and column 0 are implicit base cases — an empty string has an LCS of length 0 with anything, which is exactly what .fill(0) already gives every cell before the loop runs. dp[i][j] only ever depends on the cell diagonally above-left, directly above, or directly left — every one of those is guaranteed already filled by the time row-major order reaches (i, j). This is the same “cache overlapping subproblems” idea as Days 25-26, just stretched across 2 dimensions instead of 1. Time O(m × n), space O(m × n) for the table.
Complexity — all 4 problems
Section titled “Complexity — all 4 problems”| Problem | Time | Space | Pattern |
|---|---|---|---|
| Longest Palindromic Substring | O(n²) | O(1) | Expand around center (two-pointer variant) |
| Merge Intervals | O(n log n) | O(n) | Sort + one linear pass |
| Rotting Oranges | O(rows × cols) | O(rows × cols) | Multi-source BFS |
| Longest Common Subsequence | O(m × n) | O(m × n) | 2D Dynamic Programming |
Interview corner
Section titled “Interview corner”-
What do you do if you finish with time still on the clock? Don’t stop — trace your code against the given example out loud, then think of an edge case the example doesn’t cover (empty input, all-identical elements, a single element) and trace that too. Finishing early and using the remaining time to verify is a stronger signal than finishing early and going quiet.
-
What do you do if the timer runs out before you’re done? Keep going — say so out loud (“I’m past my time budget, let me finish this last piece”), and finish the thought. Afterward, honestly identify which phase ate the extra time (usually clarifying too long, or debugging code that was never hand-traced first) so the next mock session budgets it better.
⚠ Trap: panicking and abandoning a mostly-correct approach to try something completely different with 5 minutes left is almost always worse than finishing the original plan a few minutes late.
-
What should “talking while coding” actually sound like? Short, present-tense narration of what you’re about to type and why — “I’m sorting by end time here because that’s what makes the greedy choice safe” — not a monologue explaining the whole algorithm before you’ve written a line, and not silence. Interviewers are listening for your reasoning to stay visible the entire time, not just at the start.
-
Why do multiple timed mock sessions matter more than one long untimed one? Time pressure calibration is a skill with its own learning curve, separate from knowing the algorithms — the first few timed attempts are almost always slower than expected, purely from the unfamiliar pressure of narrating out loud while a clock runs. That gap closes with repetition, the same way any timed skill improves with practice under the actual constraint, not practice without it.
↳ Common follow-up: “How many mock sessions before it stops feeling this awkward?” — there’s no universal number, but most people notice a real difference by their 4th or 5th timed attempt. Re-run today’s 4 problems again in a few days once the solutions have faded from memory.
1. What’s the recommended first move when a timer starts on a new problem?
a) Clarify the problem and constraints, then state a brute-force approach and its complexity
b) Start writing code immediately to save time
c) Work silently until you have the complete optimal solution
Show answer
a) — The recommended order is: clarify the problem and constraints, state a brute-force approach and its complexity out loud, identify the actual pattern, write the code, then trace a test case. Skipping straight to code without naming the brute force first is one of the most common ways candidates lose interviewer confidence early.
2. Why state a brute-force approach out loud even if you’re not going to code it?
a) It proves you understand the problem’s baseline and gives the interviewer a concrete starting point to follow
b) It’s a waste of time and should always be skipped
c) LeetCode requires a brute-force submission before an optimal one
Show answer
a) — Naming the brute force and its complexity out loud — even if you never write it — proves you understand the problem’s baseline and gives the interviewer a concrete starting point to follow your reasoning from, before you jump to something cleverer.
3. If the countdown timer hits zero and you’re not done, what should you do?
a) Keep going, say so out loud, and finish the thought
b) Immediately restart with a completely different approach
c) Stop entirely — the attempt no longer counts
Show answer
a) — Keep going and finish the thought, saying out loud that you’re past the time budget — abandoning a mostly-correct approach for something completely new with little time left is almost always the worse move.
4. If you finish a problem with time remaining, what’s the best use of the rest of the clock?
a) Trace your code against the example, then test an edge case it doesn’t cover
b) Stay quiet and wait for the interviewer to speak
c) Rewrite the entire solution from scratch in a different language
Show answer
a) — Extra time is best spent tracing your code against the given example out loud, then testing an edge case the example doesn’t cover (empty input, all-identical elements, a single element) — that’s a stronger signal than finishing and going silent.
5. Why does repeating timed mock interviews matter more than one long untimed practice session?
a) Time-pressure calibration is its own skill that improves specifically through repeated timed practice
b) It doesn’t matter — untimed practice is exactly as effective
c) The only benefit is memorizing the specific 4 problems used today
Show answer
a) — Time-pressure calibration is its own skill, separate from knowing the algorithms — it improves with repeated timed practice, the same way any skill performed under a real constraint improves faster than the same skill practiced without that constraint.