JavaScript Coding Interview Patterns to Know
Learn the JavaScript coding interview patterns that cover most questions: two pointers, sliding window, BFS, DP and more, with clean code and clear triggers.
The JavaScript coding interview patterns worth memorizing are two pointers, sliding window, binary search, prefix sums, monotonic stacks, BFS/DFS, union find, heaps, backtracking, and dynamic programming. Most interview problems are variations of these ten or so ideas, so recognizing the trigger words in a prompt matters more than memorizing individual solutions. This guide gives you the trigger, a compact JS snippet, and the main pitfall for each pattern.
TL;DR
- Learn about ten core patterns instead of grinding hundreds of unrelated problems.
- Match the prompt's wording to a pattern: "sorted" suggests two pointers or binary search, "contiguous" suggests sliding window or prefix sums, "dependencies" suggests topological sort.
- JavaScript has no built-in heap or deque, so know how to write a minimal heap and avoid
Array.shift()in hot loops. - Always state the state, transition, and complexity out loud before coding.
- Practice by pattern in blocks, then mix problems to train recognition.
- Tools like CloakAI can support live practice and real-time guidance, but you still need to understand the pattern yourself.
How Do You Recognize Which Pattern a Problem Needs?
Read the prompt for structural clues rather than topic names. The input shape and the question being asked usually point to one family of solutions.
| Clue in the prompt | Likely pattern |
|---|---|
| Sorted array, pair or triplet | Two pointers |
| Longest/shortest contiguous substring | Sliding window |
| "Minimum X such that feasible" | Binary search on answer |
| Subarray sum equals k | Prefix sum + Map |
| Next greater/smaller element | Monotonic stack |
| Prerequisites, ordering | Topological sort |
| Connected groups, cycles | Union find or DFS |
| All combinations/permutations | Backtracking |
| Overlapping subproblems, max/min/count ways | Dynamic programming |
A useful habit: before coding, say "this looks like X because Y" in one sentence. Interviewers reward that reasoning as much as the final code.
What Are the Array and String Patterns?
Two Pointers
Use two indices that move toward each other (or in the same direction) when the data is sorted or can be partitioned. Moving a pointer must always make progress toward the answer.
// Does a sorted array contain two values that add to target?
function hasPair(nums, target) {
let l = 0, r = nums.length - 1;
while (l < r) {
const s = nums[l] + nums[r];
if (s === target) return true;
s < target ? l++ : r--;
}
return false;
}
This runs in O(n) time and O(1) space, versus O(n²) for brute force.
Sliding Window
Expand the right edge to include elements, then shrink the left edge until the window is valid again. Use it for longest or shortest contiguous ranges.
// Longest substring with at most k distinct characters
function longestKDistinct(s, k) {
const count = new Map();
let left = 0, best = 0;
for (let right = 0; right < s.length; right++) {
count.set(s[right], (count.get(s[right]) || 0) + 1);
while (count.size > k) {
const c = s[left++];
count.set(c, count.get(c) - 1);
if (count.get(c) === 0) count.delete(c);
}
best = Math.max(best, right - left + 1);
}
return best;
}
When the alphabet is fixed (such as 26 lowercase letters), a length-26 array is faster than a Map.
Prefix Sums with a Hash Map
Store running totals so any subarray sum becomes a subtraction. Seed the map with {0: 1} to count subarrays that start at index 0.
function countSubarraysWithSum(nums, k) {
const seen = new Map([[0, 1]]);
let sum = 0, ans = 0;
for (const x of nums) {
sum += x;
ans += seen.get(sum - k) || 0;
seen.set(sum, (seen.get(sum) || 0) + 1);
}
return ans;
}
Unlike a sliding window, this works even when the array contains negative numbers.
Monotonic Stack
Keep a stack of indices whose values stay ordered. Each index is pushed and popped at most once, giving O(n) overall.
function dailyTemperatures(t) {
const res = new Array(t.length).fill(0);
const stack = [];
for (let i = 0; i < t.length; i++) {
while (stack.length && t[i] > t[stack.at(-1)]) {
const j = stack.pop();
res[j] = i - j;
}
stack.push(i);
}
return res;
}
How Do Binary Search Patterns Work?
Classic binary search finds a target in a sorted array. The more powerful variant searches over the answer space: if a candidate value works, every larger (or smaller) value also works.
// Smallest capacity that ships all packages within `days`
function shipWithinDays(weights, days) {
let lo = Math.max(...weights);
let hi = weights.reduce((a, b) => a + b, 0);
const feasible = cap => {
let need = 1, load = 0;
for (const w of weights) {
if (load + w > cap) { need++; load = 0; }
load += w;
}
return need <= days;
};
while (lo < hi) {
const mid = (lo + hi) >> 1;
feasible(mid) ? (hi = mid) : (lo = mid + 1);
}
return lo;
}
Pick one interval convention, either [lo, hi) or [lo, hi], and stay consistent. Mixing them is the most common source of infinite loops.
Which Graph Patterns Should You Know in JavaScript?
BFS and DFS
Use BFS for shortest paths in unweighted graphs and DFS for exploring regions such as islands. Because Array.shift() is O(n), use an index pointer as your queue head:
function shortestPath(graph, start, goal) {
const dist = new Map([[start, 0]]);
const queue = [start];
for (let i = 0; i < queue.length; i++) {
const u = queue[i];
if (u === goal) return dist.get(u);
for (const v of graph[u]) {
if (!dist.has(v)) { dist.set(v, dist.get(u) + 1); queue.push(v); }
}
}
return -1;
}
Topological Sort
When the prompt mentions prerequisites or build order, compute in-degrees, start from zero-degree nodes, and process them with a queue. If you process fewer nodes than exist, there is a cycle.
Union Find
Use it for connectivity and cycle detection in undirected graphs. With path compression and union by rank, operations are effectively constant time.
class DSU {
constructor(n) { this.p = [...Array(n).keys()]; this.rank = Array(n).fill(0); }
find(x) { return this.p[x] === x ? x : (this.p[x] = this.find(this.p[x])); }
union(a, b) {
a = this.find(a); b = this.find(b);
if (a === b) return false;
if (this.rank[a] < this.rank[b]) [a, b] = [b, a];
this.p[b] = a;
if (this.rank[a] === this.rank[b]) this.rank[a]++;
return true;
}
}
How Do You Handle Heaps in JavaScript Interviews?
JavaScript has no native priority queue, so you either write a small binary heap or, when n is tiny, sort an array. Writing a MinHeap with push and pop takes about 25 lines and is worth rehearsing until you can type it from memory. Heaps power top-k problems, merging k sorted lists, and Dijkstra's shortest path. Ask the interviewer up front whether you may assume a heap library; if not, implement your own.
When Should You Use Backtracking, Greedy, or Dynamic Programming?
- Backtracking: Enumerate all choices with the loop "choose, explore, unchoose." Add pruning (skip duplicates, stop when a sum exceeds the target) to cut the search tree.
- Greedy with sorting: Sort intervals by end time, then take whatever fits. Justify it with an exchange argument: swapping any optimal choice for the greedy one never makes things worse.
- Dynamic programming: Define the state, the transition, the base cases, and the complexity, in that order. Many 1D problems compress to two variables.
// House Robber: max sum with no two adjacent picks
function rob(nums) {
let skip = 0, take = 0;
for (const x of nums) [skip, take] = [take, Math.max(take, skip + x)];
return take;
}
For deeper practice on state design, see our dynamic programming interview questions and answers.
How Should You Practice These Patterns?
Work in pattern blocks first, then shuffle. A structured schedule helps; our 8-week coding interview roadmap shows one way to sequence topics. For each problem, follow these steps:
- Restate the problem and confirm constraints.
- Name the pattern and why it fits.
- State time and space complexity before coding (review how to explain Big O in coding interviews).
- Code, then trace one small example by hand.
- Test edge cases: empty input, single element, duplicates, negatives.
If you want an assistant during practice sessions or live prep, CloakAI is an invisible AI interview assistant that can suggest approaches and surface the relevant pattern in real time. For a comparison of options, see the best AI coding interview assistants. Check each employer's and platform's rules on outside assistance before using any tool in a real assessment. Learn more at CloakAI.
FAQ
Q: How many JavaScript coding interview patterns do I need to learn? A: Around ten to twelve cover most questions: two pointers, sliding window, binary search, prefix sums, monotonic stack, BFS/DFS, topological sort, union find, heap, backtracking, greedy, and dynamic programming.
Q: Does JavaScript have a built-in heap or priority queue? A: No. You need to implement a small binary heap yourself or sort an array when the input is small. Practice writing a MinHeap so it takes only a few minutes.
Q: Why is Array.shift() a problem in BFS?
A: shift() can be O(n) because elements may need re-indexing. For large inputs, use an index pointer over an array, or a linked-list queue, to keep BFS linear.
Q: What is the difference between a sliding window and a prefix sum? A: Sliding window needs a condition that stays consistent as you shrink or grow, which usually requires non-negative values. Prefix sums with a Map work with negatives and count exact-sum subarrays.
Q: Can CloakAI help me during coding interviews? A: CloakAI is built as an invisible real-time AI interview assistant that can help you identify patterns and structure answers. Always follow the interview platform's and employer's policies on outside tools.
Conclusion
Strong interview performance comes from recognition, not volume. Learn the ten core patterns, rehearse the JavaScript-specific workarounds for queues and heaps, and narrate your reasoning as you code. With that foundation, unfamiliar problems start to look like combinations of tools you already own.
Preparing for a live interview? See how CloakAI helps in real time →