Limited-time offer: 80% off every plan

See plans

Code Optimization Coding Interview: Reason About Speed Out Loud

Optimization in a coding interview is a spoken skill. Learn a four-beat loop — state the cost, find the bottleneck, change one thing, re-state the cost — with three worked examples you can rehearse.

By Emily Miller12 min read

When an interviewer asks whether you can optimize your solution, they are rarely asking for a single correct rewrite. They are asking you to show your reasoning: where the cost is, why it is there, what one change would remove it, and what you give up in return. In a code optimization coding interview, the answer is a short spoken loop you can rehearse — state the current cost, find the real bottleneck, propose one change, then re-state the cost.

This article walks through that loop, then applies it to three small problems with concrete traces you can practise tonight. Nothing here is a script to recite. It is a way of thinking out loud that holds up when the problem is unfamiliar.

What Interviewers Actually Mean by "Can You Optimize This?"

Optimization in an interview is a conversation about cost, not a hunt for the one true answer. The interviewer is watching for three things.

First, can you estimate cost? That means saying roughly how the work grows as the input grows, in plain words before you reach for notation.

Second, can you find the dominant term? Most solutions have one part that dominates everything else. Naming it is more useful than listing the cost of every line.

Third, can you explain why a change helps? "Just use a hash map" is a weak answer on its own. A strong answer says what the hash map removes: the repeated scan through the list that made each lookup grow with the number of items.

It also helps to know that you are allowed to stop. "This is fast enough for the stated input size, and here is why" is a complete, professional answer. Interviewers often respect a candidate who can justify not optimizing more.

Start With a Cost Sentence, Not a Rewrite

Before you change a line, say one sentence about the current cost. Keep it to three parts: the input size, the dominant operation, and roughly how it grows.

For example: "For each of the n items I scan the rest of the list, so the work grows with n squared."

Plain language first, notation second. If you lead with O(n²) the interviewer learns that you know a symbol. If you lead with the sentence above, they learn that you understand the mechanism, and the symbol becomes a summary rather than a guess.

Name what you are counting. Comparisons, array writes, hash lookups, network calls and allocations all behave differently. Saying "this counts hash lookups, not comparisons" shows you know which resource is under pressure.

This is the step candidates skip under pressure. Practise saying the cost sentence out loud until it takes five seconds. It buys you thinking time and gives the interviewer something to follow.

Find the Bottleneck Before You Touch the Code

Once the cost sentence is out, locate the expensive part. Three questions help.

Ask which part of the input grows. Is the expensive work per element, per pair, or per query? Per-pair work is what turns a single loop into a nested one, and it is the most common source of accidental quadratic behaviour.

Separate setup cost from per-operation cost. A one-time sort costs more than nothing, but if you then answer many lookups cheaply, the setup can pay for itself. Say the crossover out loud: "this is worth it once we do more than a handful of queries."

Distinguish the algorithmic bottleneck from constant-factor noise. A tighter loop or a cheaper comparison shaves time, but it does not change the growth. Interviewers usually want the first kind of change, and saying which kind you are proposing keeps the conversation honest.

If the input is small and bounded, say so. Optimizing a fixed-size loop that runs a dozen times is usually the wrong use of interview time, and pointing that out is a sign of judgement rather than laziness.

Worked Example: From Nested Loop to Single Pass

Take a simple problem: does any value repeat in a list?

Run it on [3, 1, 3]. The naive version compares the first element with the two after it (two comparisons), then the second with the one after it (one comparison). Three comparisons for three items. Add a fourth item and you add three more comparisons; the count grows with the square of the input size. In words: "as the list doubles, the work roughly quadruples."

The optimized version keeps a set of values already seen and makes one pass. On [3, 1, 3]: add 3, add 1, then check 3 — already seen, so stop. Three checks, one per element, and the work grows in step with the list.

Now say the trade-off explicitly. You are spending extra memory proportional to the input, in exchange for removing the inner scan. That is the sentence interviewers are listening for, because it shows you know optimization is rarely free.

Add the honest caveat: for a tiny fixed-size list, the nested version may be perfectly fine, and the set adds allocation overhead for no real gain. Naming that boundary is a strength, not a hedge.

Worked Example: Precomputation and Prefix Sums

Now suppose you must answer many range-sum queries over the same array: add up the values between two positions, again and again.

Take the array [2, 4, 1, 5]. A query for positions 1 to 2 (zero-based) means 4 + 1 = 5. The naive version adds the range each time, so the cost grows with the length of the range, per query. If queries are frequent and ranges are long, that repeated work is the bottleneck.

The optimized version builds a running total once. Store the sum of everything up to each position, with a leading zero: [0, 2, 6, 7, 12]. The same query is now running[3] - running[1], which is 7 − 2 = 5. One subtraction, whatever the range length.

The reasoning pattern to narrate: repeated work over the same data is a candidate for precomputation. You are not making any single query clever — you are moving the effort to a single upfront pass.

Name the trade-off: upfront cost and extra storage, in exchange for cheaper repeated queries. Then say when it is not worth it — a handful of queries on a short array does not justify the extra pass or the memory.

Worked Example: Choosing the Right Structure for Lookups

Suppose the problem needs repeated membership checks and counts. Take the list [5, 7, 5, 9] and the question "how many times does 5 appear?"

A list scan looks at items one at a time: four comparisons here, and the cost grows with the list length each time you ask. A set gives average constant-time membership. Worst case can differ, so check your language. A map goes further and keeps a value alongside each key, which is what you want for counts: one pass builds {5: 2, 7: 1, 9: 1}, and each later count is a single lookup.

Explain why the choice changes the growth of the whole solution, not just one line. If membership checks sit inside a loop over the input, an expensive lookup turns a linear solution into a quadratic one. That is the sentence that connects the data structure to the complexity.

Mention the reasons you might not reach for the fastest structure. Ordering matters if you need to iterate in insertion or sorted order. Memory matters if the input is large. Sometimes a plain list is the right call because the code stays readable and the input is small.

Keep it honest: if you are unsure how a structure behaves in a given language, say what you would check. "I would confirm whether this preserves insertion order before relying on it" is a better answer than a confident guess.

If you want more practice connecting structures to trade-offs, our post on Python interview questions: concepts and trade-offs covers the same reasoning from a language angle.

How to Talk About Time and Space Without Guessing

You will not always know the exact complexity. Give a range or a shape, then narrow it.

"At worst this is quadratic, but in practice it is closer to linear because the inner loop usually exits early." That is a real answer, and it is more useful than a precise number you cannot defend.

State your assumptions before you quote growth. Input size, whether the data is sorted, whether values repeat, whether queries are batched. Complexity claims are conditional, and saying the condition out loud makes the claim stronger, not weaker.

Treat space as a first-class part of the answer. "This runs in one pass but keeps a set that can grow to the size of the input" is a complete answer. Memory pressure is often the reason a faster approach is rejected in real systems.

When the interviewer corrects you, restate the corrected reasoning in your own words rather than simply agreeing. "So the bottleneck is actually the repeated sort, not the lookup — that changes what I would fix first." That restatement is the signal they are looking for.

Common Code Optimization Coding Interview Questions and How to Approach Them

These code optimization interview questions come up constantly. Each has a shape of answer that works.

"Can you do better than this?"

Name the bottleneck, then propose one concrete change. One change, not three. If it helps, say what the new cost would be before you write it, so the interviewer can follow your intent.

"What is the time complexity of your solution?"

Count the dominant operation, not every line. Find the part that grows fastest with the input and describe that. Mention the smaller terms only if they matter for the input sizes in play.

"What would you change if the input were ten times larger?"

Talk about growth and memory pressure. A ten-times-larger input punishes anything quadratic and anything that stores a copy per element. This question is really asking whether you know which of your costs scale.

"Is there a trade-off here?"

Name what you gave up: memory, readability, ordering, or setup time. Then say why the trade is acceptable for this problem. A trade-off you can name is a decision; a trade-off you cannot name is a risk.

"How would you test that it is actually faster?"

Describe comparing the two versions on realistic input sizes rather than asserting that yours is better. Say what you would measure — wall-clock time, number of operations, peak memory — and note that tiny inputs often hide the difference entirely.

Rehearsing Optimization Reasoning Before the Real Thing

Reasoning out loud is a skill, and like any skill it improves with repetition. Here is a short routine.

Practise the four-beat pattern out loud: state cost, find bottleneck, propose one change, re-state cost. Do it on problems you have already solved, so you can focus on the words rather than the puzzle. A code optimization coding interview rewards the candidate who has said these sentences many times before.

Record yourself and check whether you named a trade-off every time. Most candidates describe the improvement and forget the cost. The recording makes that gap obvious.

Re-solve the same problem a day later and try to reach the optimized version faster. Speed comes from familiarity with the pattern, not from memorizing answers.

Use the same pattern in written practice. If you always write a one-line cost note above your solution, the spoken version will feel familiar when you are nervous.

Keep the framing honest throughout. This is preparation for your own reasoning, not a script to recite, and interviewers can tell the difference. The goal is to be the person who can look at unfamiliar code and say, calmly, where the cost is and what you would change first.

If you want to go further, browse our blog for more practice material.

Frequently asked questions

Do I need to optimize every coding interview solution?

No. Many interview problems are designed so that a clear, correct solution at the expected complexity is enough. What matters is that you can say what the cost is and justify why further optimization is or is not worth it for the stated input size.

What if I cannot find a better approach during the interview?

Say what you have tried and where you got stuck. Name the bottleneck you identified and one direction you would explore, then ask whether the interviewer wants you to pursue it. Showing the search is often worth more than producing a finished optimization.

Should I state time complexity before or after I write the code?

Before, in plain language, then confirm it after. A one-sentence cost estimate before you write gives the interviewer a map of your intent, and re-stating it afterwards shows you checked your own assumption rather than guessing.

How do I talk about trade-offs without sounding unsure?

Name the specific thing you gave up — memory, ordering, readability or setup time — and say why that is acceptable for this problem. A trade-off stated as a decision sounds confident; one you cannot name sounds like a risk you have not noticed.

Is it acceptable to say the naive solution is good enough?

Yes, when you can justify it. If the input is small and bounded, say so and explain that the extra structure would add memory and complexity for no practical gain. That is a judgement call, not a failure to optimize.

How can I practise optimization reasoning on my own?

Re-solve problems you already know and narrate the four beats out loud: state the cost, find the bottleneck, propose one change, re-state the cost. Record yourself and check that you named a trade-off each time, then repeat the same problem a day later to build speed.

Practise the four-beat loop on your own problems.