Arrays and Strings: The Coding Interview Patterns
Arrays and strings are the most common coding-interview problem type. Here are the handful of patterns — two-pointer, sliding window, hash maps, prefix sums — that solve the vast majority of them in O(n).
Array and string problems are the most common type you’ll meet in a coding interview, and the good news is that a small set of patterns — two-pointer, sliding window, hash maps, and prefix sums — solves the overwhelming majority of them. Learn to recognise which pattern a problem fits and you’re most of the way to the answer.
They dominate interviews for a reason: an array is the simplest structure to pose a problem with, yet it supports techniques rich enough to separate “brute-forces everything” from “finds the O(n) insight.” That insight is what’s being graded.
The mindset: brute force, then optimise
Almost every array problem has an obvious O(n²) brute force (check every pair, every subarray) and a clever O(n) solution. Interviewers want to see you state the brute force, then improve it. The patterns below are those improvements.
Pattern 1 — Two pointers
Two indices moving through the array replace a nested loop. On a sorted array, a pointer at each end finds a target pair in O(n):
// Find two numbers that sum to target (sorted array)
let lo = 0, hi = arr.length - 1;
while (lo < hi) {
const sum = arr[lo] + arr[hi];
if (sum === target) return [lo, hi];
sum < target ? lo++ : hi--; // move the pointer that helps
}
Reach for it on sorted arrays, palindrome checks, reversing in place, and partitioning. Full guide: the two-pointer technique.
Pattern 2 — Sliding window
For problems about a contiguous subarray or substring with a running constraint (max sum of size k, longest substring without repeats), slide a window and expand/shrink it in a single O(n) pass:
// Max sum of any window of size k
let sum = 0, best = 0;
for (let i = 0; i < arr.length; i++) {
sum += arr[i];
if (i >= k) sum -= arr[i - k]; // slide: drop the left edge
if (i >= k - 1) best = Math.max(best, sum);
}
Full guide: the sliding-window pattern.
Pattern 3 — Hash map for instant lookup
When you’d otherwise search the array inside a loop (O(n²)), a hash map remembers what you’ve seen and makes each check O(1):
// Two-sum on an UNsorted array → O(n)
const seen = new Map();
for (let i = 0; i < nums.length; i++) {
const need = target - nums[i];
if (seen.has(need)) return [seen.get(need), i];
seen.set(nums[i], i);
}
This is the most common single optimisation in all of array interviewing.
Pattern 4 — Prefix sums
When a problem asks for many range sums, precompute a running total so each query is O(1):
// prefix[i] = sum of arr[0..i-1]
const prefix = [0];
for (const n of arr) prefix.push(prefix.at(-1) + n);
// sum of arr[i..j] = prefix[j + 1] - prefix[i] → O(1) per query
Prefix sums turn repeated O(n) range queries into O(1) lookups, and underpin “subarray sum equals k” problems (combined with a hash map).
Strings: arrays with one twist
Treat strings as arrays of characters — the same patterns apply — but mind immutability. In Java, Python, and JavaScript, strings can’t be changed in place, so building a result with repeated += concatenation is secretly O(n²):
// Slow: O(n²) — each += rebuilds the whole string
let out = "";
for (const c of chars) out += c;
// Fast: O(n) — collect, then join once
const parts = [];
for (const c of chars) parts.push(c);
const out2 = parts.join("");
Common string problems — anagrams, palindromes, character frequency — usually reduce to a hash map of counts or a two-pointer scan.
Common mistakes
- Off-by-one errors at array boundaries — the most frequent array bug. Be deliberate about
<vs<=andlength - 1. - Modifying an array while iterating it forward — iterate backward or build a new array.
- String concatenation in a loop — O(n²); collect and join instead.
- Forgetting the array is unsorted — the two-pointer-from-both-ends trick needs sorted data; sort first (O(n log n)) or use a hash map.
Where this fits
Arrays and strings are Phase 2 of the coding interview roadmap and the launchpad for the two-pointer and sliding-window patterns, often combined with hash maps.
These patterns are drawn out with diagrams and worked problems in our job-ready tier — JavaScript in Three Months, Python in Three Months, and Java in Three Months. For the trickier variants (sliding-window-maximum with a deque, substring problems with complex state) seen in senior rounds, the for Staff Engineers tier goes deeper: JavaScript, Python, Java.
Name the pattern before you write code, and array problems stop being puzzles.
Frequently asked questions
Why are array and string problems so common in interviews?
Arrays and strings are the simplest structures to state a problem with, yet they support a rich set of techniques — two-pointer, sliding window, hashing, prefix sums. That makes them ideal for testing whether you can move from a brute-force O(n²) idea to an efficient O(n) one, which is exactly what interviewers want to see.
What patterns should I learn for array problems?
The core four are: the two-pointer technique (pairs and partitions in sorted arrays), the sliding window (contiguous subarrays with a constraint), hash maps (fast lookup to avoid nested loops), and prefix sums (fast range-sum queries). Most array and string interview questions are a variation of one of these.
Are strings just arrays of characters?
Conceptually yes — a string is an ordered sequence of characters, and most array techniques apply. The key difference is that strings are immutable in many languages (Java, Python, JavaScript), so building a result by repeated concatenation is O(n²); use a list or string builder and join once instead.
How do I turn an O(n²) array solution into O(n)?
Usually by replacing a nested search with a hash map (remember what you have seen), or by using two pointers or a sliding window so you make a single pass instead of comparing every pair. Spotting that move is the most common array-interview optimisation.