Coding Interviews

How to Explain Your Approach in a Coding Interview

Learn how to explain your approach in a coding interview with a clear talk-through framework, worked example, complexity analysis, and recovery phrases.

The Stealth Interview Team12 min read
How to Explain Your Approach in a Coding Interview

How to explain your approach in a coding interview comes down to making a few things visible: your assumptions, your decisions, your trade-offs, and your checks. You do not need to broadcast every thought. You need to give the interviewer enough context to follow your reasoning and redirect you when necessary.

What Interviewers Need From Your Explanation#

A useful explanation shows how you move from an ambiguous prompt to a validated solution.

Interview rubrics vary. Some interviews emphasize correctness. Others spend more time on code quality, complexity, testing, or collaboration. You may not know the rubric, but you can still make the important parts of your work observable.

Your talk-through should reveal:

  • What you believe the problem asks.
  • Which details could change the solution.
  • Why you chose a particular algorithm or data structure.
  • What must remain true while the algorithm runs.
  • How you know the result is correct.
  • What the solution costs in time and space.

That is productive coding interview communication. It differs from narrating every mental branch.

Avoid streams of consciousness such as:

Maybe I could use a map. Actually, perhaps a list. Let me type this loop first. Now I am adding one.

This gives the interviewer activity without a clear plan.

Do not read code aloud either:

I set left to zero. Then I increment right. Then I enter the if.

Instead, explain the purpose:

This window contains the current valid range. I move the right boundary to explore, then advance the left boundary only when the constraint fails.

The second version exposes the invariant and the reason for each pointer.

Clear narration also gives the interviewer a chance to correct a misunderstanding early. Suppose the prompt says to process intervals, but does not define whether touching intervals overlap. Saying your assumption aloud lets the interviewer clarify it before you build the wrong comparison into the code.

Treat the explanation as a shared model of the problem. You own the implementation, but the interviewer should be able to see where your model came from.

A Framework for Explaining Any Coding Approach#

Use the same sequence for most problems: restate, clarify, exemplify, solve, implement, analyze, and test.

Restate the contract#

Start by describing the input, output, and required transformation in your own words.

I receive a collection of intervals. I need to combine intervals that overlap and return the resulting non-overlapping intervals.

This is not ceremony. It catches differences between what was written, what was said, and what you inferred.

Confirm details such as:

  • Whether you return a value or modify the input.
  • Whether the input has a guaranteed order.
  • Whether duplicate values are possible.
  • Whether indices or values should be returned.
  • What should happen for empty input.
  • Whether the input has useful size constraints.

Ask questions that can change the solution#

Good coding interview clarification questions affect correctness, complexity, or implementation.

For intervals, useful questions include:

  • Are interval endpoints inclusive?
  • Do touching intervals count as overlapping?
  • Can an interval have equal start and end values?
  • Is the input already sorted?
  • May I reorder or mutate the input?

A question such as “Should I write clean code?” does not resolve the problem. Neither does asking for every constraint when only one matters to your approach.

If the interviewer tells you to make a reasonable assumption, state it and continue:

I will treat endpoints as inclusive, so [1,4] and [4,5] overlap.

Walk through a small example#

A concrete example often exposes the algorithm before formal discussion does.

For example:

Text
[[1,3], [2,6], [8,10], [9,12]]

The first two intervals merge into [1,6]. The last two merge into [8,12]. The result is:

Text
[[1,6], [8,12]]

Use an example that contains the important behavior. A set of completely separate intervals would not help you reason about overlap.

Establish a baseline when it helps#

You do not always need a brute-force solution. Use one when it reveals the bottleneck.

You might say:

I could repeatedly compare intervals and merge any overlapping pair. That can cause repeated scans because each merge changes the collection. The main difficulty is finding possible overlaps efficiently.

Then improve the structure:

If I sort by start value, any interval that can extend the current merged interval appears next in the scan. That removes the need to search the whole collection after every merge.

This shows progression without spending several minutes implementing an approach you already expect to replace.

State the algorithm and invariant before coding#

Before touching the editor, name three things:

  1. The ordering or traversal strategy.
  2. The data structure that holds state.
  3. The invariant that explains correctness.

For merge intervals:

I will sort by start value and scan from left to right. The output list stores the merged result for all intervals processed so far. Before each iteration, those output intervals are ordered and non-overlapping.

That statement gives your code a target. If the implementation stops matching it, you have a precise way to diagnose the problem.

Close the loop#

After implementation:

  • Derive time complexity.
  • Derive auxiliary and output space.
  • Trace representative tests.
  • Revisit any assumptions.

This repeatable coding interview problem-solving framework prevents the common pattern of writing code first and explaining it afterward.

Worked Example: Talking Through Merge Intervals#

LeetCode 56, Merge Intervals is a useful example because the key idea is simple, but the explanation still needs precision.

The problem gives you a list of intervals. You must merge all overlapping intervals and return a collection of non-overlapping intervals covering the same values.

Clarify the overlap rule#

You could begin like this:

I want to confirm that endpoints are inclusive. If one interval ends at the same value where another starts, should I merge them? I also want to know whether I may reorder the input.

Assume touching intervals overlap and you may return a new collection.

Now use:

Text
[[1,3], [2,6], [8,10], [9,12]]

Sorting by start does not change this example. Start the merged list with [1,3].

  • [2,6] starts before the current interval ends, so extend the end to 6.
  • [8,10] starts after 6, so it begins a new merged interval.
  • [9,12] overlaps [8,10], so extend the end to 12.

The result is:

Text
[[1,6], [8,12]]

The reason sorting works is local. Once intervals are ordered by start, the next interval can only overlap the final interval in the merged list. It cannot reach back and overlap an earlier merged interval without also overlapping the final one.

Implement the stated approach#

Python
def merge_intervals(intervals):
    if not intervals:
        return []

    ordered = sorted(intervals, key=lambda interval: interval[0])
    merged = [ordered[0][:]]

    for start, end in ordered[1:]:
        last = merged[-1]
        if start <= last[1]:          # Inclusive endpoints overlap.
            last[1] = max(last[1], end)
        else:
            merged.append([start, end])

    return merged

The comments identify a consequential rule. They do not substitute for the spoken explanation.

The invariant is:

After processing each input interval, merged is sorted, contains no overlapping adjacent intervals, and represents exactly the union of all intervals processed so far.

There are two cases.

If the next interval overlaps merged[-1], extending the final endpoint preserves ordering and captures the new interval. Earlier merged intervals remain unchanged.

If it does not overlap, its start is greater than the final endpoint. Because the input is sorted by start, it cannot overlap any earlier merged interval either. Appending it preserves the invariant.

Derive the cost#

Sorting n intervals takes O(n log n) time. The scan visits each interval once and performs constant work per visit, so it takes O(n) time. Sorting dominates, giving O(n log n) total time.

This implementation creates a sorted copy containing n intervals. The returned list can also contain n intervals when none overlap. Its auxiliary space is O(n) because of the copied collection, and its output space is O(n).

That explanation is stronger than saying “sort and scan, so O(n log n).” It identifies the operations that produce the bound.

How to Narrate While You Code#

Narrate the purpose of each block, then stay quiet long enough to implement it.

Before writing the sort, say:

I am sorting by start value so potential overlaps become adjacent.

Before the loop:

The merged list represents everything processed so far. Each new interval either extends its last entry or starts a new one.

This style explains the code at the right level. You do not need to announce variable names or punctuation.

Call out choices that affect behavior:

  • Loop boundaries: Explain why you start from the second item.
  • Mutation: Say whether you modify the input, a copy, or the output.
  • Comparison operators: Explain whether touching boundaries overlap.
  • Helpers: State what a helper guarantees, not merely that you created one.
  • Data structures: Connect the structure to the required operation.

Use short pauses at structural points. After the main loop, compare the code with your invariant:

The loop has the two cases I described. On overlap, it changes only the final merged interval. Otherwise, it appends a later non-overlapping interval.

If you notice a mistake, correct it directly:

I used <, which would treat touching intervals as separate. Under the inclusive-endpoint assumption, this needs to be <=. I will change that and use [1,4] with [4,5] as a boundary test.

That response identifies the error, connects it to an assumption, fixes it, and adds a test. It does not require an apology or a long explanation.

How to Talk Through Time and Space Complexity#

Identify the operations that scale with the input before stating a Big-O bound.

For time complexity, ask:

  • Is there a sort?
  • How many times can each element enter a loop?
  • Can a pointer move backward?
  • Does a nested loop repeat work, or do its pointers move only forward?
  • What does a library call do to a collection?
  • Does recursion branch or follow one path?

For space complexity, separate:

  • State required by the algorithm.
  • Recursion stack depth.
  • Copies created by slicing, sorting, or conversion.
  • The returned output, when the distinction matters.

A concise explanation for merge intervals is:

Sorting the intervals costs O(n log n). The scan is O(n) because it processes each interval once, so total time is O(n log n). This code also creates a sorted copy, which costs O(n) auxiliary space. The returned merged list uses up to O(n) output space.

Be careful with claims about “in-place” operations. Mutating the input may remove one explicit copy, but the language’s sorting implementation can still use memory internally. State what your code clearly allocates, then note implementation-dependent costs if they matter.

When explaining algorithms in interviews, derivation matters more than reciting the final notation. Tie each term to a visible operation.

What to Say When You Get Stuck or Receive a Hint#

When you get stuck, summarize your current model and name the exact unresolved step.

Avoid:

I am blanking.

Use:

Sorting makes overlapping intervals adjacent. I am now checking whether I need to compare the next interval with every merged interval or only the last one.

That gives the interviewer something specific to respond to.

A practical recovery sequence is:

  1. State what you know.
  2. Identify the obstacle.
  3. Reduce it to a small example.
  4. Propose the next experiment.

Useful phrases include:

The current approach is correct on this example, but it repeats work when I search earlier elements.

I need a structure that supports removing the smallest item efficiently. I am comparing a sorted list with a heap.

My invariant fails when the right pointer moves past the duplicate. I will trace that transition before changing the loop.

When the interviewer gives a hint, acknowledge it and connect it to your current approach:

Using a stack would let me compare the current value with the most recent unresolved value. That replaces the backward scan in my current approach.

Do not imply that you had already reached the same idea:

Right, that is what I was about to do.

That adds nothing. A hint is part of the conversation. Show that you understand what it changes.

If the hint invalidates your plan, reset cleanly:

My previous approach depended on checking every pair. With the ordering property you pointed out, I can sort first and reduce the remaining work to one scan. I will restate the invariant before implementing that change.

Recovery is not separate from how to think aloud in a coding interview. It is where clear thinking aloud becomes most useful.

Test the Solution Out Loud#

Test one normal case, one boundary case, and one adversarial case, with each test tied to a possible failure.

For merge intervals, you might choose:

  • Normal: [[1,3], [2,6], [8,10]]
  • Boundary: [[1,4], [4,5]]
  • Adversarial: [[1,10], [2,3], [4,8]]

Explain why each exists.

The normal case checks both loop branches. The boundary case checks the inclusive comparison. The adversarial case checks that a contained interval does not shrink the current endpoint.

A useful trace focuses on changing state:

Text
merged = [[1,10]]
next = [2,3]
2 <= 10, so merge
new end = max(10, 3) = 10
merged remains [[1,10]]

You do not need to read every variable after every line. Track only the state that determines the next decision.

Depending on the problem, also consider:

  • Empty input.
  • A single item.
  • Duplicate values.
  • Already sorted and reverse-ordered input.
  • All values equal.
  • Minimum and maximum boundaries.
  • Off-by-one transitions.
  • Inputs where no items combine.
  • Inputs where every item combines.

Connect tests to assumptions. If you asked whether duplicates were allowed, include a duplicate case. If your loop uses right < len(values), test the final valid index.

Practise the Talk-Through, Not Just the Code#

Practise producing an understandable explanation under the same constraints as the implementation.

Record a short solution. Then review it without looking at the original prompt. Check whether you can identify:

  • The input and expected output.
  • The assumptions.
  • The chosen algorithm.
  • The invariant.
  • The reason the algorithm is correct.
  • The source of the complexity bounds.
  • The purpose of each test.

Use familiar problems at first. Familiarity reduces the algorithmic load and lets you focus on how to talk through a coding problem. Do not memorize a script. Repeat the same problem with a stricter communication goal.

For one attempt, focus on asking fewer, higher-value questions. For another, state the invariant before coding. On another, derive complexity from operations without using a memorized sentence.

For structured practice, choose problems from the algorithm pattern hubs. The sorting pattern collection is a natural next step after merge intervals. You can also work through a fixed sequence such as the Blind 75 list instead of selecting unrelated problems.

Use this checklist before you code:

  • Contract: What are the input, output, and mutation rules?
  • Clarifications: Which unanswered details could change the solution?
  • Example: What small case exposes the important behavior?
  • Baseline: Is there a simple correct approach worth stating?
  • Bottleneck: What repeated or expensive work should be removed?
  • Plan: What algorithm and data structure will you use?
  • Invariant: What remains true after each step?
  • Implementation: Which boundaries or mutations deserve explanation?
  • Complexity: Which operations determine time and space?
  • Tests: Which normal, boundary, and adversarial cases challenge the assumptions?

The goal is not continuous speech. It is a concise conversation in which your reasoning remains visible from clarification through testing.

Frequently asked questions

How should I explain my approach in a coding interview?
Restate the problem, clarify details that affect the solution, walk through an example, and state your algorithm and invariant before coding. After implementation, derive the time and space complexity, test representative cases, and revisit your assumptions.
Should I narrate every thought while coding?
No. Explain the purpose of each code block, important decisions, and behavior-changing choices rather than reading code aloud or sharing every mental branch.
What should I say before I start coding?
Describe the traversal or ordering strategy, the data structure that holds state, and the invariant that should remain true. This gives the implementation a clear target.
How do I explain time and space complexity in an interview?
Identify the operations that scale with the input, then connect each Big-O term to those operations. Separate algorithm state, recursion depth, allocated copies, and output space when relevant.
What should I say when I get stuck during a coding interview?
Summarize what you know, identify the exact obstacle, reduce it to a small example, and propose the next experiment. If you receive a hint, explain how it changes your current approach.

Keep reading

Ace your next coding interview

Stealth Interview is a desktop app for macOS and Windows that reads the problem off your screen and answers with a working solution, a step-by-step explanation and its time and space complexity — while staying invisible to screen sharing.

Get Stealth Interview