DSA · Interview Method

How to Approach a New DSA Problem in a Coding Interview, Step by Step

A repeatable six-step method for problems you have never seen, a full worked interview dialogue from clarification to tested code, and what to do in the minute you get stuck.

✍️ Pranjal Jain, Ex-Microsoft · IIT Kanpur 📅 10 October 2026 ⏱ 15 min read
A climber following six glowing handholds up a cliff, representing a step-by-step method for coding problems
TL;DR
  • Use the same six steps every time: Clarify → Examples → Brute force → Optimise → Code → Test. The fixed order keeps you moving when the clever idea has not arrived yet.
  • Constraints pick the algorithm: n ≤ 20 exponential is fine, n ≤ 5,000 means O(n²), n ≤ 105 to 106 means O(n log n) or O(n).
  • Optimise by naming the bottleneck in your brute force ("I recompute this sum every time") and picking the data structure that removes it.
  • Get agreement on the approach before coding. Then test with a dry-run table and edge cases out loud.
  • The worked example below (Subarray Sum Equals K) shows the full dialogue, including the clarifying question that rules out the sliding window most people reach for.

Most people who fail coding rounds do not fail because they lack knowledge. They fail because they meet an unfamiliar problem, panic, jump to code with a half-formed idea, and spend the last fifteen minutes debugging something that was never going to work. A fixed procedure fixes that. It turns "I have no idea" into a list of next actions, and it shows the interviewer the problem-solving signal they are actually grading.

This guide gives you that procedure, explains what to do and say in each step, and then runs a complete mock interview on a real problem so you can see the steps working together.

The Six-Step Method at a Glance

StepGoalOutput before moving onTypical time (45-min round)
1. ClarifyRemove ambiguityInput types, ranges, edge cases, output format agreed2 to 4 min
2. ExamplesUnderstand by hand2 to 3 worked examples, including one tricky case2 to 4 min
3. Brute forceGuarantee a baselineCorrect naive approach + its complexity2 to 3 min
4. OptimiseReach target complexityApproach the interviewer agrees with5 to 10 min
5. CodeClean, correct implementationComplete code with good names12 to 18 min
6. TestFind your own bugsDry run + edge cases + final complexity4 to 7 min

These steps are not original to me; versions of them appear in most interview prep material (some call it UMPIRE: Understand, Match, Plan, Implement, Review, Evaluate). What matters is doing them visibly and in order, every time, including in practice.

Step 1: Clarify the Problem Before Anything Else

Restate the problem in one sentence in your own words, then ask about the things that change the algorithm. Not every question is worth asking; ask the ones whose answer would change your approach.

QuestionWhy it matters
What is the size of n? Range of values?Sets the target complexity and whether you need long to avoid overflow
Can values be negative or zero?Negatives break sliding window and many greedy ideas
Are there duplicates?Affects hashing, binary search bounds and "distinct" counting
Is the input sorted? Can I modify it?Sorted input suggests two pointers or binary search; sorting in place may be disallowed
What should I return if there is no answer? Empty input?Avoids a wrong sentinel like 0 vs -1
Multiple valid answers: return any or all?"All" can change output size and complexity
Graph: directed? connected? cycles? self-loops?Picks between BFS, topological sort, union-find
Strings: character set? case sensitive?Fixed-size array vs hash map for counts
💡
Constraints are hintsAbout 108 simple operations fit in a second. So n ≤ 20 hints at backtracking or bitmasks, n ≤ 500 allows O(n³), n ≤ 5,000 allows O(n²), and n around 105 to 106 demands O(n log n) or O(n). If the interviewer has not said n, ask. The Big-O guide has the full table.

Step 2: Work Through Examples by Hand

Write two or three small inputs and solve them manually, saying what you do. This is where the algorithm usually reveals itself, because your hands do something smarter than brute force without you noticing. Watch what you naturally track.

  • One normal case big enough to be non-trivial (6 to 8 elements).
  • One edge case: empty, single element, all same, all negative.
  • One adversarial case that breaks the obvious idea, if you can think of it. Finding it early saves you from building on a wrong idea.

Agree on the expected output for each with the interviewer. If your example's answer differs from theirs, you have just found a misunderstanding at minute 4 instead of minute 35.

Step 3: State the Brute Force and Its Complexity

Describe the most direct correct solution: try every pair, every subarray, every subset. Give its time and space complexity. You usually do not code it. Its job is threefold:

  1. It proves you understand the problem.
  2. It gives you a fallback. A working O(n²) beats a broken O(n).
  3. It shows where the waste is, which is the starting point for step 4.

Keep it short: "The brute force checks every pair, O(n²) time and O(1) space. With n up to 105 that is 1010 operations, too slow, so let me find the repeated work."

Step 4: Optimise by Attacking the Bottleneck

Do not stare at the problem hoping for inspiration. Point at the specific part of the brute force that costs the most and ask which tool removes it. This table covers most interview problems:

Bottleneck in brute forceTool that removes it
Inner loop searching for a matching valueHash map / hash set (O(1) lookup)
Recomputing the sum of a rangePrefix sums
Checking every pair in a sorted arrayTwo pointers
Recomputing a window as it shiftsSliding window (non-negative or monotonic condition)
Searching a monotonic yes/no conditionBinary search (on index or on answer)
Repeatedly finding the min/maxHeap, or monotonic deque for windows
"Next greater / previous smaller" scansMonotonic stack
Recomputing the same subproblem in recursionMemoisation / DP
Exploring states, shortest stepsBFS; Dijkstra if weighted
Repeated "are these connected?" queriesUnion-find
Prefix lookups over many stringsTrie

Two more questions that unlock many problems: "Would sorting help?" (costs O(n log n) but often enables two pointers or greedy) and "What if I process from the right, or fix one element and solve the rest?"

When you have an approach, explain it and get a nod before coding. Say the complexity. If the interviewer asks "can you do better?", it usually means yes; if they say "sounds good, go ahead", start coding.

Step 5: Write Clean Code, Not Fast Code

  • Use descriptive names: prefixSum, seenCount, left, not a, m, t.
  • Write the skeleton first: function signature, main loop, return. Then fill in the body.
  • Extract helpers for distinct pieces (e.g. isValid(row, col), neighbors(node)). If time is short, leave a well-named stub and say you will fill it.
  • Narrate intent, not syntax. "Now I store the prefix sum so later indices can look it up" is useful; "now I write a for loop" is noise.
  • Handle edge cases explicitly at the top if they are not naturally covered.

Step 6: Test Your Own Code Like a Reviewer

Do not say "I think this works". Prove it. First, read your code once, line by line, looking for off-by-one errors, wrong variable names and missing returns. Then dry-run a small example with a variable table. Finally run through edge cases mentally: empty, single element, duplicates, negatives, overflow at max constraints.

When you find a bug, say "I found a bug here" calmly and fix it. Finding your own bugs is scored positively; interviewers pointing them out is not.

A Full Worked Interview: Subarray Sum Equals K

Here is how the method plays out on LeetCode 560. Read it as a script: the candidate's moves are the point, not just the final code.

Interviewer: Given an integer array nums and an integer k, return the number of contiguous subarrays whose sum equals k.

Clarify

Candidate: So I count every pair (i, j) with i ≤ j where nums[i] + ... + nums[j] == k. A few questions. How large can the array be?

Interviewer: Up to 2 × 104. Values between -1000 and 1000, k between -107 and 107.

Candidate: So values can be negative. That matters: a sliding window assumes that growing the window increases the sum, which is false with negatives, so I will not use a window. Overlapping subarrays each count separately? And for an empty array I return 0?

Interviewer: Yes and yes.

⚠️
The question that saves the roundMany candidates hear "subarray sum" and start writing a sliding window. With negative numbers that silently gives wrong answers. One clarifying question about the value range rules it out before any code is written.

Examples

Candidate: Let me take nums = [1, 1, 1], k = 2. Subarrays [1,1] at positions 0-1 and 1-2, so the answer is 2. A trickier one with negatives: [3, 4, -7, 1, 3, 3, 1, -4], k = 7. By hand: [3,4], [3,4,-7,1,3,3], [1,3,3], [3,3,1]. That is 4. Edge case: [5], k = 5 gives 1, and [0, 0], k = 0 gives 3 since [0], [0], [0,0] all count.

Interviewer: Agreed.

Brute force

Candidate: The direct approach: for each start i, extend j to the right keeping a running sum, and count when it equals k. That is O(n²) time and O(1) space. With n = 2 × 104 that is 4 × 108 basic steps in the worst case, borderline. I would like something linear.

Optimise

Candidate: The repeated work is summing ranges. If I define prefix[j] as the sum of the first j+1 elements, then the sum of i..j is prefix[j] - prefix[i-1]. I want that to equal k, so for each j I need the number of earlier prefixes equal to prefix[j] - k. That is a lookup, so I keep a hash map from prefix sum to how many times I have seen it. I seed it with {0: 1} for the empty prefix, so subarrays starting at index 0 are counted. One pass, O(n) time, O(n) space.

Interviewer: Why do you need counts rather than a set?

Candidate: Because with zeros and negatives the same prefix sum can appear several times, and each earlier occurrence gives a different valid start. In [0, 0] with k = 0, prefix 0 appears three times counting the seed.

Interviewer: Good, go ahead.

Code

Python
from collections import defaultdict

def subarray_sum(nums, k):
    count = 0
    prefix = 0
    seen = defaultdict(int)   # prefix sum -> number of times seen
    seen[0] = 1               # empty prefix, for subarrays starting at 0
    for x in nums:
        prefix += x
        count += seen[prefix - k]   # earlier prefixes that leave sum k
        seen[prefix] += 1
    return count
C++
int subarraySum(const vector<int>& nums, int k) {
    unordered_map<long long, int> seen;
    seen[0] = 1;
    long long prefix = 0;
    int count = 0;
    for (int x : nums) {
        prefix += x;
        auto it = seen.find(prefix - k);
        if (it != seen.end()) count += it->second;
        seen[prefix]++;
    }
    return count;
}

Candidate (while coding): I look up before inserting the current prefix, otherwise with k = 0 I would count the empty subarray ending here. In C++ I use find instead of seen[prefix - k] so I do not insert useless zero entries.

Test

Candidate: Dry run on [3, 4, -7, 1, 3, 3, 1, -4], k = 7:

xprefixprefix - kseen[prefix-k]countseen after
33-400{0:1, 3:1}
47011+ 7:1
-70-7010:2
11-601+ 1:1
34-301+ 4:1
370237:2
18114+ 8:1
-44-3044:2

Candidate: Final count is 4, matching my manual answer. Edge cases: empty array never enters the loop, returns 0. [0, 0], k = 0: first 0 sees seen[0] = 1, count 1; second sees seen[0] = 2, count 3. Correct. Overflow: max prefix is 2 × 104 × 1000 = 2 × 107, which fits in an int, but I used long long in C++ anyway. Final complexity: O(n) time, O(n) space for the map.

Interviewer: What if I asked for the longest subarray with sum k instead?

Candidate: Then I store the first index at which each prefix sum appears instead of a count, and for each j take j - firstIndex[prefix - k]. Storing only the first occurrence maximises the length. Still O(n).

Notice what happened: the optimal idea came from step 4's question "what am I recomputing?", the critical correctness detail (no sliding window) came from step 1, and the off-by-one around insert-before-lookup was caught and explained during step 5. None of that needed a flash of genius.

What to Do When You Get Stuck

Getting stuck is normal and interviewers plan for it. What they grade is how you behave while stuck. Work through this list out loud:

  1. Say where you are. "I have O(n²); the bottleneck is finding the partner element. I am looking for a way to avoid the inner loop."
  2. Go back to examples. Solve a bigger one by hand and watch what you track mentally.
  3. Run the pattern checklist. Sort? Hash? Two pointers? Window? Binary search on the answer? Heap? Stack? Prefix sums? Graph? DP? For each, spend ten seconds asking "what would that look like here?"
  4. Simplify the problem. Solve it for sorted input, for non-negative values, for k = 1, for a tree that is a line. Then generalise.
  5. Ask a targeted question. "Would it help to think of this as a graph?" is better than "Can I get a hint?" Both are acceptable.
  6. Use the hint fully. Repeat it in your words and connect it to your approach. Taking a hint well is a positive signal; ignoring it is a negative one.
  7. Fall back. With about 15 minutes left and no optimal idea, code the brute force cleanly and discuss how you would optimise it. A working, tested solution scores better than an unfinished clever one.

Silence is the real failure mode. If you are thinking, say what you are thinking; the guide on thinking out loud has phrases that keep you talking without sounding scripted.

A 45-Minute Time Budget That Works

MinuteActivityWarning sign
0 to 5Intros (often), problem statementLong intros eat your time; keep yours to 60 seconds
5 to 10Clarify + examplesStill no examples at minute 12
10 to 18Brute force, optimise, agreeCoding with no agreed approach
18 to 35CodeStill on line 5 at minute 30
35 to 42Dry run, edge cases, complexitySaying "I think it works" with no dry run
42 to 45Follow-ups, your questionsNo time left for questions

Many Indian product companies (and Google, Microsoft, Amazon India loops) run 45 to 60 minute rounds, sometimes with two problems. With two problems, halve each block and move faster through the brute-force step. Confirm the format with your recruiter; it varies by company and team.

How Interviewers Score You on Each Step

Rubrics differ by company, but most product-company feedback forms cover similar dimensions:

DimensionWhat earns a strong ratingWhat hurts
Problem solvingClarifies, explores options, justifies the choiceJumps to code, cannot explain why the approach works
Algorithms and complexityCorrect Big-O, recognises the right patternWrong complexity, unaware of better options
CodingClean, idiomatic, readable, few bugsMessy names, copy-pasted blocks, language misuse
VerificationDry runs, finds own bugs, considers edge casesRelies on the interviewer to find bugs
CommunicationExplains reasoning, takes hints wellLong silences, argues with hints

The six-step method maps directly onto these: steps 1 to 4 produce the problem-solving and complexity signal, step 5 the coding signal, step 6 the verification signal, and doing them all aloud produces the communication signal. If you are getting rejections despite solving problems, this table is usually why; why engineers fail interviews goes through the other common causes.

How to Practise the Method Until It Is Automatic

  • Write the steps as comments at the top of your file for the first 30 practice problems: # clarify, # examples, # brute, # optimise, # code, # test. Fill each one before moving on.
  • Practise on unseen problems with a timer. Familiar problems train recall, not method. LeetCode contest problems and company-tagged problems you have not solved are ideal.
  • Record yourself solving one problem a week out loud. Watching it back is uncomfortable and extremely effective.
  • Do mocks with a human. A partner who interrupts with questions forces you to keep the structure under pressure. The mock interview strategy guide covers how to run them.
  • Build your pattern vocabulary. Step 4 is only as good as the tools you can name. Work through the core DSA patterns so the bottleneck table above feels obvious.
✅
The one-sentence versionUnderstand it, solve it badly, find the waste, remove it with the right tool, write it cleanly, and prove it works, all out loud.

Frequently Asked Questions

How do I approach a coding problem I have never seen before?▾
Use a fixed sequence: clarify the input and constraints, work through two or three examples by hand, state a brute-force solution and its complexity, look for the bottleneck in the brute force and remove it with a suitable data structure or pattern, then code, and finally test with a dry run and edge cases. The fixed sequence keeps you making progress even when the optimal idea is not obvious.
Should I tell the interviewer the brute-force solution?▾
Yes, briefly. Stating the brute force with its time complexity shows you understand the problem, gives you a fallback if you cannot find the optimum, and often reveals the bottleneck that the optimal solution removes. Do not spend long coding it unless the interviewer asks or you are clearly stuck.
What should I do if I get stuck in a coding interview?▾
Say what you are trying and why it fails, then go back to concrete examples and look for repeated work in your brute force. Run through the pattern checklist: sorting, hashing, two pointers, sliding window, binary search, heap, prefix sums, BFS or DFS, DP. If you still have nothing after a few minutes, ask a focused question such as whether a particular property holds; interviewers expect to give hints and grade how you use them.
How much time should I spend before starting to code?▾
In a 45-minute round with one medium problem, aim to spend roughly 10 to 15 minutes on clarification, examples and approach, then 15 to 20 minutes coding and 5 to 10 minutes testing. Coding before you and the interviewer agree on the approach is the most common way to run out of time.
How do constraints tell me which algorithm to use?▾
Input size limits the acceptable complexity. Roughly 10^8 simple operations run in about a second, so n up to 20 allows exponential, n up to 500 allows O(n^3), n up to 5000 allows O(n^2), and n up to 10^5 or 10^6 needs O(n log n) or O(n). Ask for the constraints if the interviewer does not state them.
Is it okay to ask the interviewer questions during a coding round?▾
Yes, and it is expected. Good clarifying questions about input ranges, duplicates, negative numbers, empty input and expected output format are part of what is evaluated. Avoid asking the interviewer to confirm every line of code; ask about requirements, not about whether your code is correct.
How do I test my code in an interview without running it?▾
Dry-run one normal example line by line, tracking variables in a small table, then check edge cases such as empty input, a single element, all equal values, negative numbers and the largest input size for overflow. Say what you are checking out loud so the interviewer sees the testing process.

Practise the Method Under Real Pressure

Prepflix mock interviews put this six-step method to work on unseen problems with ex-FAANG interviewers, and give you a written score on each step so you know exactly what to fix.

Explore the Prepflix Course →
Pranjal Jain
Pranjal Jain

Ex-Microsoft SDE · IIT Kanpur · Founder of Prepflix. Helps engineers crack startup and product company interviews across India.