Pattern Recognition — How to Spot Two Sum in Interviews

This page teaches you how to recognise the Two Sum pattern (LeetCode 1) quickly during an interview, map it to the right algorithm (brute force, two-pointer, one-pass hash map), and explain your choice confidently in Java, Python, or JavaScript. Learn the signals, the decision tree, ASCII flows, and interviewer prompts you should ask out loud.

Quick signals / keywords to listen for

  • "two numbers", "pair", "sum equals", "add up to" — classic Two Sum clue.
  • "return indices" — must preserve original positions (favors hash map).
  • "return values" — you may use two-pointer if input is/ can be sorted and indices are not required.
  • "exactly one solution" — allows early exit; you can return when found.
  • "return all pairs" — different problem: expect output-size complexity discussion (may need sorting or counting).
  • "array sorted" or "already sorted" — two-pointer approach becomes ideal (O(n) time, O(1) extra).
  • "streaming" or "online" — memory and windowing constraints matter; hash map must be bounded.

Decision tree — which approach to pick

Decision: What did interviewer ask?
  ├─ Is the array already sorted? --- Yes --> Use two-pointer (values-only) → O(n), O(1)
  │                                     (If indices required: sort with index pairs and map back → O(n log n))
  │
  ├─ Return indices? ------------------ Yes --> Use one-pass hash map → O(n), O(n)
  │
  ├─ Return all pairs? ---------------- Yes --> Sort + two-pointer with duplicate skipping OR hashmap with counts
  │
  └─ None of above / small n? --------- Fallback --> Brute force (show correctness then optimize)
    

Pattern mapping table — clues → algorithm

CluePattern / AlgorithmWhy it fitsComplexity (Time / Space)
Return indices, unsorted array One-pass hash map (value → index) Lookup complement in O(1) average while preserving original indices O(n) / O(n)
Array sorted, return values Two-pointer (left, right) Move pointers inward based on sum; no extra map needed O(n) / O(1)
Return all pairs, duplicates possible Sort + two-pointer or hashmap with counts Need to avoid duplicates and enumerate all combinations O(n log n) or O(n + k) depending on output size
Small n or first thought Brute-force (nested loops) Simple correctness proof; good to state before optimizing O(n²) / O(1)

Pattern templates — mental snippets to memorize

  • “Indices required” → think: hash map (value to index); check complement before insert.
  • “Sorted input” → think: two-pointer (left/right) and shrink search space.
  • “All pairs” → think: deduplicate & enumerate (sorting helps remove duplicates).
  • “Streaming” → think: bounded window + hash map / external storage.

ASCII flows — visualising the two main interview choices

One-pass hash map (indices required)

nums: [2, 7, 11, 15], target = 9
i=0: x=2, complement=7
  seen = {}
  seen.has(7)? NO
  insert 2->0   seen = {2:0}

i=1: x=7, complement=2
  seen.has(2)? YES -> return [seen.get(2), 1] => [0,1]

Flow (abstract):
  Read x
    ├─ complement = target - x
    ├─ if seen.has(complement) -> found pair
    └─ else seen.set(x, i)
    

Two-pointer (values only, array sorted)

values: [2, 7, 11, 15]   target = 9
l = 0 (2), r = 3 (15)    sum = 17 > 9 -> r--
l = 0 (2), r = 2 (11)    sum = 13 > 9 -> r--
l = 0 (2), r = 1 (7)     sum = 9 == 9 -> found pair (2,7)

Note: If original indices required, sort pairs like [(2,0),(7,1),(11,2),(15,3)], use two-pointer on values, then map back to original indices.
    

Interviewer prompt — what to ask immediately

  • “Are the nums already sorted, or can I sort them?”
  • “Should I return indices or values?”
  • “Is there always exactly one solution or should I return all pairs?”
  • “What are the constraints on n (array size) and value ranges?”
  • “Is there any memory limit I should be aware of (e.g., streaming/online requirement)?”

Interview-ready explanation template (what to say, step-by-step)

  1. Restate problem & constraints — "I will return indices of two numbers whose sum equals target. Are the nums sorted, and is there exactly one solution?"
  2. Baseline — "A brute-force nested loop checks pairs in O(n²). It’s correct but slow for large n."
  3. Optimal pick — "If indices are required and array is unsorted, I’ll use a one-pass hash map (value→index) for O(n) time and O(n) space. If input is already sorted and indices not required, two-pointer gives O(n) time and O(1) space."
  4. Brief dry-run — Walk through one short example (2–3 steps). Use ASCII if the interviewer allows a whiteboard.
  5. Edge cases & complexity closing — Mention duplicates, negative values, minimal length, and time/space complexity.

Pattern recognition checklist (10–15 seconds scan)

  • Look for words: pair, two numbers, indices, sum, target, sorted.
  • If "indices" appears → default to hash map unless they say input is sorted.
  • If "sorted" appears → consider two-pointer and ask about indices.
  • If "all pairs" → ask whether duplicate pairs should be unique; consider sorting + skipping duplicates.
  • If "stream" or "online" → discuss windowing / bounded memory approaches.

Mapping to code languages (how to say it concisely)

  • “I’ll implement one-pass hash map — in Java use HashMap<Integer,Integer>, in Python use a dictionary, in JavaScript use a Map or object depending on keys.”
  • “If asked for two-pointer, I’ll explain sorting pairs and mapping back to original indices in the chosen language.”

Common follow-up traps — how to answer fast

  • What if there are multiple valid pairs? — "LeetCode 1 guarantees one; if multiple are possible, we must enumerate all pairs and discuss output-size complexity (possibly O(n²))."
  • Can we do O(1) extra space? — "Only if indices are not required and in-place sorting is allowed; that changes time to O(n log n)."
  • What about negative numbers / zero? — "Hash map handles negatives and zero fine. For duplicates we check complement before inserting to avoid self-match."
  • What if array length is huge (streaming)? — "We need to bound memory with a sliding window or external storage; discuss constraints and trade-offs."

Practice recognition exercises (do these aloud)

  1. Read prompt: "Return indices of two nums adding to target" → say "hash map" and why.
  2. Read prompt: "Array is sorted; return values" → say "two-pointer" and outline pointer moves.
  3. Read prompt: "Return all unique pairs" → say "sort + two-pointer with duplicate skipping" and mention complexity concerns.

Final note

Memorize the decision tree and the mental pattern templates. In interviews, candidates who quickly map the prompt to one of these templates (brute force → optimize to hash map or two-pointer) and then communicate the trade-offs clearly are rated higher.

Interview-Focused — Short Answer to Deliver (Two Sum)

"Start with a brute-force to show correctness (two nested loops). Then use a one-pass hash map: for each element compute complement = target - x, check map for complement, return indices if found; otherwise store x -> index. This gives O(n) time and O(n) space. Check duplicates and edge cases; if input were sorted, we could use two pointers instead."

One-minute checklist to say

  • State brute and why it's slow.
  • State hash map approach and complexity.
  • Do a short dry-run on sample input.
  • Mention edge cases and follow-ups.

Interview Script & What to Say (Two Sum)

Step-by-step script (word-for-word suggestions)

  1. "I'll restate the problem: given nums and target, return indices of two numbers that add up to target. Are the nums sorted and should I return indices or values?"
  2. "A brute-force approach checks all pairs in O(n²). This is correct but too slow for large n."
  3. "A better approach is to use a hash map storing value→index. For each x, compute complement = target - x. If the complement exists in the map, return the stored index and current index; otherwise insert x into the map. This is O(n) time and O(n) space."
  4. Dry-run a small example out loud (e.g., [2,7,11,15],9)."
  5. "Edge cases: duplicates like [3,3] handled by checking complement before insert, negative numbers are fine, minimal size 2, and some variants may not guarantee a solution."

What the interviewer hears

  • Clear problem understanding and constraints checking.
  • Ability to articulate a baseline and then optimize with correct data structure choice.
  • Concise complexity analysis and edge-case coverage.

Solution Approach — Two Sum (JavaScript-focused)

Always ask these clarifying questions first

  • "Should I return indices or values?"
  • "Is the array already sorted or can I sort it?"
  • "Is there exactly one solution or should I return all pairs?"
  • "Are there constraints on n or memory (streaming)?"

Brute-force — baseline (say this quickly)

State the brute-force to show correctness and move to optimization. Keep it short in interview.

// Brute-force: O(n^2) time, O(1) extra
function twoSumBrute(nums, target) {
  const n = nums.length;
  for (let i = 0; i < n - 1; i++) {
    for (let j = i + 1; j < n; j++) {
      if (nums[i] + nums[j] === target) return [i, j];
    }
  }
  return [];
}

Two-pointer — when input is sorted or values-only

Use two-pointer if the array is sorted or the problem returns values (not indices). If indices are required, sort pairs and map back.

Values-only (array already sorted)

function twoSumTwoPointerValues(sortedNums, target) {
  let l = 0, r = sortedNums.length - 1;
  while (l < r) {
    const s = sortedNums[l] + sortedNums[r];
    if (s === target) return [sortedNums[l], sortedNums[r]]; // values
    if (s < target) l++; else r--;
  }
  return [];
}

Indices required — sort (value, index) pairs then two-pointer

function twoSumTwoPointerIndices(nums, target) {
  const pairs = nums.map((v, i) => ({v, i}));
  pairs.sort((a, b) => a.v - b.v);
  let l = 0, r = pairs.length - 1;
  while (l < r) {
    const sum = pairs[l].v + pairs[r].v;
    if (sum === target) return [pairs[l].i, pairs[r].i];
    if (sum < target) l++; else r--;
  }
  return [];
}

One-pass Hash Map — default interview optimal (indices)

Key idea: iterate once; for each x compute complement = target - x. If complement exists in map, return indices; otherwise store x -> i. Check complement before inserting current (prevents self-match for duplicates).

// One-pass map: O(n) time, O(n) space — recommended answer for LeetCode 1
function twoSum(nums, target) {
  const seen = new Map(); // value -> index
  for (let i = 0; i < nums.length; i++) {
    const x = nums[i];
    const complement = target - x;
    if (seen.has(complement)) {
      return [seen.get(complement), i];
    }
    seen.set(x, i);
  }
  return [];
}

Why check complement first (say this in interview)

  • Prevents matching element with itself when x * 2 === target.
  • Correctly handles duplicates like [3,3] → target 6.
  • Shows interviewer you considered edge-cases explicitly.

One-pass dry-run (step-by-step, JavaScript mindset)

Input: nums = [2, 7, 11, 15], target = 9
i=0: x=2, complement=7
  seen = {}      -> seen.set(2,0)
i=1: x=7, complement=2
  seen.has(2) -> true -> return [0,1]
    

Detailed trace (table)

ixcomplementseen beforeaction
027{}seen.set(2,0)
172{2:0}found -> return [0,1]

LLD-like flow (whiteboard-friendly, short)

Input nums ---> iterate (i)
    |           compute complement = target - nums[i]
    |           check HashMap(seen) for complement
    |              -> found: return [seen.get(complement), i]
    |              -> not found: seen.set(nums[i], i) and continue
    

Time & Space (quick table)

ApproachTimeSpaceWhen to use
Brute-forceO(n²)O(1)Tiny n or show correctness
Two-pointer (sorted)O(n) or O(n log n) with sortO(1) values-only; O(n) if mapping indicesSorted input or values-only
One-pass Hash MapO(n)O(n)Default for indices & unsorted arrays

Interview script — short and exact (what to say, then code)

  1. "I'll restate: return indices of two numbers whose sum equals target. Are the nums sorted and is there exactly one solution?"
  2. "Baseline: brute-force checks all pairs in O(n²) — correct but slow."
  3. "Optimal: one-pass hash map (value → index) giving O(n) time and O(n) space. I'll check complement before inserting current value to handle duplicates."
  4. Write the JavaScript two-pass/one-pass snippet and run a 2–3 step dry-run out loud.

Micro-optimizations & JS notes

  • Use Map to avoid prototype key pitfalls and preserve insertion semantics. For integer keys a plain Object works but beware coercion.
  • Return immediately when found to avoid extra work.
  • For very large numeric ranges and performance-critical hot loops, avoid repeated allocations inside loop bodies where possible.

Common pitfalls to call out in interview

  • Using indexOf inside a loop — turns O(n) lookups into O(n²).
  • Inserting current value before checking complement — causes self-match issues.
  • Assuming unique values — explain handling of duplicates explicitly.

Practice cases to run (say them aloud and dry-run)

  1. [2,7,11,15], target=9 → expect [0,1]
  2. [3,2,4], target=6 → expect [1,2]
  3. [3,3], target=6 → expect [0,1]
  4. [0,4,3,0], target=0 → expect [0,3]

Ready for next file?

I updated /contentFiles/two-sum/solution-approach.html to remove non-essential fluff and to use JavaScript only, with focused interview phrasing, ASCII dry-runs, and compact JS snippets. Tell me which file from your list I should rewrite next (I will not create new files — I will update the existing ones in the order you provided).

Deep Dive — Two Sum (interview-grade reasoning, JS-focused)

This deep-dive explains the rigorous reasoning you should be able to give in interviews for Two Sum (LeetCode 1). It focuses on correctness invariants, formal proofs you can say on the whiteboard, subtle edge cases, memory/time trade-offs, and practical JavaScript considerations. This section assumes you already know the one-pass hash map and two-pointer ideas — here we justify them and explore advanced variants interviewers often probe.

1. Correctness invariant (formal, what to say)

Invariant: at the start of loop iteration i, the hash map seen contains mappings for exactly the elements nums[0..i-1] (value → index). Therefore, if there exists a valid pair (a,b) with a < b, then when the loop reaches index b the value nums[a] is already present in seen, so the algorithm will detect nums[a] + nums[b] == target and return [a,b].

How to state this in interview (short): "My invariant is: before processing index i the map contains values and indices for all earlier positions. Thus if a valid earlier complement exists, we'll find it when we reach the later index — this guarantees we will find a correct pair."

2. Short formal proof sketch (sound and concise)

  1. Let the algorithm be as described: iterate i from 0..n-1, compute c = target - nums[i], if c in seen return [seen[c], i], else insert nums[i] → i.
  2. If the algorithm returns [j,i], correctness is immediate because we only return after checking nums[j] + nums[i] == target.
  3. For completeness, suppose there exists a valid pair (a,b) with a < b. By the invariant, when loop reaches b the value nums[a] has been inserted into seen. The algorithm checks c = target - nums[b] and finds nums[a], so it returns the pair — thus the algorithm finds a solution whenever one exists.
  4. Therefore algorithm is correct (it finds a valid pair) and returns indices that use distinct elements.

3. Why check complement before inserting current element (extra reasoning)

Checking first preserves the invariant that the map only contains earlier indices. If you inserted current element first and then checked for complement, you could match the element with itself in the same iteration (when x * 2 === target), which is invalid. Saying this explicitly in interview signals you considered duplicates and self-match issues.

4. Complexity — average vs worst-case, and why interviewers care

Average-case: Hash-table (Map) operations are O(1) on average, so the one-pass algorithm is O(n) time and O(n) space. This is the usual answer interviewers expect.

Worst-case caveat: In pathological cases (adversarial inputs or very poor hash function), hash-table operations can degrade toward O(n) each, making the algorithm O(n²) worst-case. Mentioning this shows depth: real hash maps mitigate this via rehashing, randomized hashing, or better hash functions; it's rare in interview problems but worth noting if the interviewer asks about robustness.

5. Amortized costs and resizing (JS notes)

Most hash map implementations (including JS engines' Map implementations) resize and rebuild the internal table as they grow; this makes individual insertions sometimes expensive but average insertion cost remains O(1) amortized. You can say: "Hash map rehashing exists, but insertions are amortized O(1)."

6. Memory layout & growth (visual explanation)

Iteration 0: seen = { nums[0] -> 0 }    // map size = 1
Iteration 1: seen = { nums[0] -> 0, nums[1] -> 1 } // map size = 2
...
Iteration k: seen holds k entries (worst-case k == i)

Memory grows linearly (O(n)) with number of distinct values seen so far. Explain: "In worst case we may store nearly all elements." 
    

7. Handling special cases & edge reasoning

  • Duplicates: Works naturally when checking complement before insert. Example: [3,3] with target 6: first 3 inserted at index 0; second 3 finds complement 3 in map and returns [0,1].
  • Zeros and negatives: No special handling required — arithmetic works for negative numbers and zero. Example: [0,4,3,0], target 0 → [0,3].
  • No solution variant: LeetCode 1 guarantees a solution; in general return [] or throw per spec and explain this to interviewer.
  • Large inputs / streaming: If input is a stream or very large, store only a bounded window (sliding window) or use external storage. You must explain the policy: time-based window, size-based window, or sampling depending on problem context.

8. Variants interviewers ask and how to respond

  • Return all unique pairs:
    • Approach A: sort and two-pointer, skipping duplicates while collecting pairs. Complexity: O(n log n) + O(k) where k is number of pairs reported.
    • Approach B: use a hash map of counts (value → frequency). Iterate keys and for each v check if target-v exists; manage counts carefully to avoid duplicates.
    • What to say: "If asked to return all pairs I'd clarify whether pairs should be unique and whether ordering matters. If uniqueness required I would either sort+two-pointer and skip duplicates or use a map of frequencies and a set of results to avoid repeats."
  • Streaming input (unbounded):
    • Explain memory concerns: storing seen values forever is not feasible. Propose a bounded policy (sliding window of last W elements) and show how you'd adapt the one-pass approach to maintain only recent indices in the map.
    • Simple JS sketch (sliding window): maintain a Map of value→index and if index < i-W remove values whose stored index is old. This bounds memory to O(W).
  • Memory-tight environment:
    • If indices are not required and you can modify input, sort in-place and use two-pointer to achieve O(1) extra space (but O(n log n) time).
    • If values fall in a small integer range, consider direct-addressing (array indexed by value) to reduce overhead — explain constraints needed.

9. Enumerating all pairs — practical JS pattern (avoid duplicates)

High-level approach using a frequency map and a Set for results (no code flood):

  1. Build a frequency map freq of values.
  2. Iterate over keys v in freq and compute u = target - v. If u in freq and (v,u) not yet added to results, add it; carefully decrement/use counts when v == u.
  3. Return unique pairs from results.

Explain this approach in words in interview; don't necessarily write the whole code unless asked.

10. JS-specific pitfalls & engine notes to mention

  • Use Map instead of plain Object for arbitrary numeric keys: Object keys are coerced to strings which can cause subtle bugs and collisions with prototype properties; Map accepts numbers directly and handles NaN correctly.
  • NaN: In JavaScript, Map treats NaN keys as equal (SameValueZero), so NaN can be used as a key safely. Plain objects cannot represent NaN reliably as a distinct key.
  • Pre-sizing: JavaScript's Map doesn't expose capacity/reserve controls; in languages like Java you can reserve capacity. You can mention this limitation if interviewer asks about micro-optimizations.
  • Equality & edge types: If inputs are not integers (e.g., floats or objects), be careful with equality semantics — clarify types with interviewer before choosing approach.

11. Micro-optimizations (say them only if asked)

  • Avoid unnecessary temporary allocations inside tight loops (e.g., repeated object creation). Use local variables where possible.
  • When using integer keys in a limited range, direct-addressing via an Array can be faster than Map (but only when range is bounded and memory allows it).
  • When the interviewer asks about performance in production, mention profiling and that algorithmic clarity usually outweighs premature micro-optimizations.

12. Debugging tips during interview (how to recover fast)

  1. If your code fails a test, repeat the failing input and dry-run your algorithm on it out loud — show the map contents step-by-step.
  2. Print or speak the seen contents at the failing index to identify off-by-one or insertion order mistakes.
  3. If you hit a self-match bug, check whether you inserted current element before checking complement.

13. What to say if interviewer asks: "Is this optimal?"

Answer: "For returning indices in an unsorted array, the one-pass hash-map is optimal in time (O(n) average) for general inputs. Space is O(n). If the interviewer wants lower extra space and indices are not required, you can trade time for space with sorting (O(n log n) time, O(1) extra)."

14. Final interview checklist (what to say in 60 seconds)

  1. Restate problem & confirm indices vs values, sortedness, multiplicity of solutions.
  2. Give brute-force baseline quickly and mention complexity.
  3. State one-pass hash-map as your choice for indices (O(n) time, O(n) space), explain invariant and complement-first check.
  4. Mention edge cases (duplicates, negative numbers, streaming) and one alternative (two-pointer after sorting) with its trade-offs.

Memorize this deep-dive flow. In interviews, use the invariant + proof sketch + complexity caveat to show both correctness and depth.

Common Pitfalls — Two Sum (and how to explain fixes in interviews)

When solving Two Sum in interviews, small mistakes often create bugs or performance issues. Understanding these pitfalls helps you both code correctly and communicate confidence during interviews.

PitfallWhy it failsHow to explain fix
Using indexOf inside a loop O(n²) time complexity — each indexOf call scans the array Explain: "Using a hash map avoids repeated scanning, giving O(n) average time."
Inserting current value before checking complement May match element with itself, especially if x * 2 == target Explain: "Check for complement first, then insert the current value to prevent self-match and handle duplicates."
Using plain object ({}) carelessly Integer keys may coerce to strings; collision with built-in keys like __proto__ Explain: "Use Map for guaranteed key behavior, avoiding subtle JS bugs."
Not considering negative numbers or zero Edge cases may fail if algorithm assumes positive integers Explain: "Two Sum works with negatives and zeros as long as we compute complement correctly."
Sorting without tracking original indices Original index positions lost — solution may return wrong indices Explain: "If indices are required, store value-index pairs when sorting or prefer hash map solution."
Assuming multiple solutions exist LeetCode 1 guarantees exactly one — code may return extra/duplicate pairs if misused Explain: "Clarify problem constraints first. If multiple solutions allowed, handle with a count map or two-pointer duplicates logic."

Debugging tips to mention in interview

  • Walk through the algorithm with a small input to show handling of duplicates, negatives, and zeros.
  • Explain why checking the complement first avoids subtle self-match bugs.
  • Use console.log or dry-run diagrams (ASCII style) to visualize the hash map or two-pointer state.
  • Mention performance trade-offs when asked — why O(n) hash map beats O(n²) brute-force.

JavaScript-specific notes

  • Map maintains insertion order — useful if you need predictable iteration.
  • Avoid Object key pitfalls: keys are strings; collisions possible for special names like __proto__.
  • Hashing of NaN behaves correctly in Map: map.set(NaN, 1) can be retrieved via map.get(NaN).
  • Always clarify whether input array may contain non-integer values in interview discussion.

Edge Cases & Suggested Interview Demos — Two Sum

In interviews, demonstrating awareness of edge cases shows depth of understanding. Two Sum has several subtle cases that can trip up beginners if not considered. Walk through these explicitly and explain why your solution handles them.

1. Minimal size array

Arrays of length 2 are the simplest valid input. Always run a quick dry-run out loud.

nums = [1, 3], target = 4
i=0: x=1, complement=3 -> seen={}
i=1: x=3, complement=1 -> seen={1:0} -> found [0,1]
    

2. Duplicates

When the same number occurs multiple times, your hash map check prevents self-match but still finds the correct pair.

nums = [3,3], target=6
i=0: x=3, complement=3 -> seen={} -> insert 3:0
i=1: x=3, complement=3 -> seen has 3 -> return [0,1]
    

3. Zeros and negative numbers

Always verify with zeros and negative numbers; complements may be negative or zero.

nums = [0, 4, 3, 0], target=0
i=0: x=0, complement=0 -> seen={} -> insert 0:0
i=1: x=4, complement=-4 -> seen has -4? no -> insert 4:1
i=2: x=3, complement=-3 -> insert 3:2
i=3: x=0, complement=0 -> seen has 0 -> return [0,3]
    

4. No valid pair (if variant allows)

Explain how your code would return [] if no pair exists, and mention that for LeetCode 1 this is guaranteed not to happen.

5. Large input arrays

For arrays up to 10⁵ elements, emphasize time and space trade-offs:

  • O(n²) brute-force is infeasible.
  • One-pass hash map remains O(n) time and O(n) space — optimal.
  • If memory is tight and indices aren’t needed, two-pointer approach with sorted values is O(n log n) time, O(1) space.

Suggested live interview demos

  1. Minimal input: [1, 3], target=4 → expect [0,1]
  2. Duplicates: [3,3], target=6 → expect [0,1]
  3. Zeros/negatives: [0,4,3,0], target=0 → expect [0,3]
  4. Regular case: [2,7,11,15], target=9 → expect [0,1]
  5. Sorted array (two-pointer demo if needed): [1,2,4,7], target=6 → left=0, right=3, adjust pointers to find sum

Interview talking points

  • Explain each edge case as you dry-run the algorithm in front of the interviewer.
  • Show that the one-pass hash map handles all situations: duplicates, zeros, negatives, and minimal-size arrays.
  • Mention time and space trade-offs when array is very large or memory is constrained.
  • Clarify assumptions and ask interviewer about constraints if not specified (sorted, multiple solutions, negative values).

Time & Space Complexity — Two Sum

Understanding time and space complexity is critical for interviews. Here we break down each approach with detailed reasoning and examples using JavaScript.

1. Brute-force approach

Check all pairs using nested loops. For array nums of length n:

for i = 0 to n-2:
    for j = i+1 to n-1:
        if nums[i] + nums[j] == target -> return [i,j]
    
  • Time complexity: O(n²) — every element pairs with every other.
  • Space complexity: O(1) — no extra data structures.
  • When to mention in interviews: Demonstrates correctness but is inefficient for large n.

2. Sorting + two-pointer approach

Applicable if array is sorted or you only need values (not indices). Steps in JavaScript:

JavaScript — Two-pointer example

const nums = [2,7,11,15].sort((a,b)=>a-b);
let left = 0, right = nums.length-1;

while(left < right) {
  const sum = nums[left] + nums[right];
  if(sum === target) return [left,right]; // values, map back if needed
  else if(sum < target) left++;
  else right--;
}
    
  • Time complexity: O(n log n) due to sorting; O(n) for pointer traversal.
  • Space complexity: O(n) if you need to map sorted indices back; O(1) if values-only.
  • When to mention: Useful if interviewer allows sorting or when memory is tight.

3. One-pass hash map — optimal

Maintains a map of previously seen numbers to their indices for O(1) complement lookup.

nums = [2,7,11,15], target = 9
seen = {} // map of value -> index

i=0: x=2, complement=7 -> not in seen -> store 2:0
seen = {2:0}

i=1: x=7, complement=2 -> found in seen -> return [0,1]
    
  • Time complexity: O(n) — each element processed once, map lookup is O(1) on average.
  • Space complexity: O(n) — stores each unique number in the map.
  • Edge discussion: Worst-case hash collisions exist but are rare; acceptable for interviews.
  • JavaScript note: Use Map for predictable iteration and key handling.

Memory usage example

For nums = [1,2,3,4,5], map stores up to 5 key-value pairs:

Index: 0 1 2 3 4
Nums : 1 2 3 4 5
Map after processing:
{1:0}, {1:0,2:1}, {1:0,2:1,3:2}, ... etc
    

Summary table

ApproachTimeSpaceNotes
Brute-force O(n²) O(1) Simple but inefficient; good to explain correctness.
Sort + two-pointer O(n log n) O(n) for indices, O(1) for values-only Useful if memory constrained; map indices if needed.
One-pass hash map O(n) average O(n) Default optimal choice; mention collisions and edge cases in interviews.

Interview tips

  • Always articulate why you picked an approach — time vs space trade-off.
  • Show dry-run with a small array to demonstrate memory usage and operations.
  • If interviewer asks about worst-case memory, explain hash map growth and alternatives like two-pointer if allowed.
  • Explicitly mention O(1) extra space for brute-force and two-pointer (values-only).

Language-Specific Notes

Implementation details for the fixed sliding window solution vary by language. Select to view optimizations.

FAQs — Two Sum LeetCode 1: Interview-Ready Answers

These are the questions that often come up in interviews around Two Sum. Memorize the flow, understand the reasoning, and practice explaining the steps clearly. All examples here use JavaScript syntax and logic for clarity.

Q1: Walk me through your Two Sum approach.

A: "I first clarify constraints: should I return indices or values, is the array sorted, and are duplicates allowed? I begin with the brute-force approach (nested loops, O(n²)) to ensure correctness. Then I explain the one-pass hash map solution: as I iterate through nums, I compute complement = target - nums[i]. If the complement exists in the Map, I return [map.get(complement), i]. Otherwise, I store nums[i] → i in the map. This achieves O(n) time and O(n) space. I mention handling duplicates, negative numbers, and minimal arrays."

Q2: Why not sort and use two pointers?

A: "Sorting costs O(n log n) and loses original index positions. If indices are required, I need to track value→index pairs and map back, which adds complexity. If indices aren't required or input is already sorted, two pointers (left/right) are efficient with O(n) time and O(1) space. I always mention the trade-off in interviews."

Q3: How do you handle duplicates like [3,3]?

A: "By checking the complement before inserting the current value into the map. For nums = [3,3], target = 6:

i=0: x=3, complement=3 -> not in map, store 3->0
i=1: x=3, complement=3 -> found in map, return [0,1]
      
This ensures no self-match and handles duplicates correctly."

Q4: Can this be done in O(1) extra space?

A: "Only if indices are not required and in-place sorting is allowed. Sorting achieves O(1) extra space but O(n log n) time. When indices are needed, mapping back to original positions requires O(n) extra space, so the one-pass hash map remains the optimal interview choice."

Q5: What if there are multiple valid pairs?

A: "LeetCode 1 guarantees exactly one solution. If a variant asks for all pairs: - Use sorting + two-pointer approach with duplicate skipping. - Or use a hash map with frequency counts to enumerate unique pairs. Complexity depends on the number of pairs returned."

Q6: Any micro-optimizations for production code?

A: "Use Map for predictable behavior; a plain object works for integer keys but requires caution. Return as soon as a valid pair is found. Avoid repeated allocations in loops. For small integer ranges, array-based direct addressing can be used, but rarely needed."

Quick Interview Follow-ups — Practice These Responses

  • Sorted array → use two pointers; explain index mapping if original positions matter.
  • All pairs required → explain duplicate skipping and output-size dependence.
  • Streaming input → discuss memory constraints and windowing strategies.
  • Edge cases: minimal arrays, zeros, negatives, duplicates — show dry-run.