Skip to main content
side by side

Which one should I use?

Every pair here is one people genuinely mix up, and each page leads with the answer rather than making you read a table to find it. The trade-off is usually not the complexity, and each comparison says what it actually is.

BFS vs DFS

Use BFS when the question asks for a shortest path or a distance in an unweighted graph. Use DFS for anything about connectivity, cycles, or ordering, and whenever the recursion itself is the answer.

Full comparison

Quicksort vs Merge Sort

Quicksort is faster in practice on arrays and is what most standard libraries use for primitives. Merge sort is the one to pick when you need a guaranteed O(n log n), a stable sort, or you are sorting a linked list.

Full comparison

Array vs Linked List

Use an array by default. Reach for a linked list only when you insert or remove in the middle and already hold a reference to the node, which is rarer than the textbook comparison suggests.

Full comparison

Stack vs Queue

A stack when the most recent item is the one you need next, which is what nesting, undo and backtracking all look like. A queue when items should be handled in arrival order, which is what fairness and level-by-level exploration look like.

Full comparison

HashMap vs TreeMap

HashMap unless you need the keys in order. TreeMap costs you a log factor on every operation and buys ordering, range queries, and the floor and ceiling lookups that a hash table cannot do at all.

Full comparison

Memoization vs Tabulation

Memoize first. It is the recursive solution plus a cache, so it is faster to write and harder to get wrong. Convert to tabulation when the recursion is too deep for the stack, or when you want to drop the table to a single row and save the memory.

Full comparison

Greedy vs Dynamic Programming

Greedy when you can argue that the locally best choice is part of some optimal solution. Dynamic programming when you cannot, which is most of the time. If you are unsure, DP is the safe answer, because it is correct wherever greedy is and in many places greedy is not.

Full comparison

Dijkstra vs Bellman-Ford

Dijkstra whenever every edge weight is non-negative, because it is much faster. Bellman-Ford when negative weights are possible, or when you need to detect a negative cycle, which Dijkstra cannot do at all.

Full comparison

Binary Search Tree vs Hash Table

A hash table for pure lookup, which is faster and simpler. A balanced BST when order matters: sorted iteration, range queries, or finding the nearest key to a value.

Full comparison

Heap vs Binary Search Tree

A heap when you only ever want the smallest or largest item. A BST when you need to look up arbitrary values, iterate in order, or query ranges. A heap is a weaker structure, and that weakness is why it is cheaper.

Full comparison

Kruskal vs Prim

Kruskal on sparse graphs, where sorting the edges is cheap. Prim on dense graphs, where there are too many edges to sort and growing outward from one node touches fewer of them.

Full comparison

Two Pointers vs Sliding Window

Sliding window is a two-pointer technique, not a rival to it. Use the window framing when the answer is a contiguous subarray or substring, and the general two-pointer framing when the pointers move for some other reason, such as converging from both ends or moving at different speeds.

Full comparison

Segment Tree vs Fenwick Tree

A Fenwick tree if you only need prefix sums with point updates, because it is a fraction of the code and uses less memory. A segment tree for anything else: minimums, maximums, range updates, or any operation that does not decompose into prefixes.

Full comparison

Recursion vs Iteration

Recursion when the problem is defined recursively, which trees, backtracking and divide and conquer all are. Iteration when the depth could be large, or when the loop is genuinely simpler to read, which for linear scans it usually is.

Full comparison