SE

Data structures and complexity

Must-know concept3 hIntermediate

Arrays, maps, sets, trees, queues, graphs, Big O, and trade-offs.

Data structures are trade-off tables with code attached. You do not need contest-level algorithms for most backend work, but you do need to know what gets slow and why.

The big idea

Every structure makes some operations cheap and others expensive.

Array / list
Fast by index, cache-friendly, slow membership checks unless sorted or small.
Map / dict
Fast lookup by key, ideal for grouping, deduping, and joins in memory.
Set
Fast membership checks when you only care whether something exists.
Queue
First-in, first-out work. Useful for jobs, BFS, and producer-consumer flows.
Tree
Ordered hierarchy. Useful for indexes, parsers, and nested categories.
Graph
Nodes and edges. Useful for dependencies, routes, social links, and workflows.

Choosing the right one is often the difference between a service that feels instant and a service that melts under real data.

Big O in plain English

Big O describes how work grows as input grows.

  • O(1)constant

    hash lookup, array index

  • O(log n)logarithmic

    binary search, B-tree lookup

  • O(n)linear

    scan one collection

  • O(n log n)sorting-ish

    many general sorts

  • O(n^2)nested loop

    often painful at scale

Big O ignores constants, network calls, disk, and memory layout. Those matter in real systems, but Big O still catches the obvious traps.

Backend examples

// Slow when users grows: scan every user for each order.
const result = orders.map((order) => ({
  ...order,
  user: users.find((user) => user.id === order.userId),
}));
 
// Better: build an index once, then do cheap lookups.
const usersById = new Map(users.map((user) => [user.id, user]));
const result = orders.map((order) => ({
  ...order,
  user: usersById.get(order.userId),
}));

That same idea appears everywhere: database indexes, caches, routing tables, dependency graphs, and queue workers.

Common choices

  1. Need membership?

    Use a Set, not repeated array.includes.

  2. Need lookup by ID?

    Use a Map or database index.

  3. Need ordered results?

    Sort once, use a tree, or let the database do it with an index.

  4. Need shortest path or dependencies?

    Model it as a graph and pick BFS, DFS, or topological sort.

Algorithms you should recognize

  • Binary search: find in sorted data.
  • BFS and DFS: traverse graphs and trees.
  • Topological sort: order tasks with dependencies.
  • Hashing: map keys to buckets; powers maps, sets, caches, sharding.
  • Sorting: know when data must be sorted and who pays for it.

In practice

Take one endpoint that loops over data. Write down the input sizes, the nested loops, and the database calls. If the endpoint does one query per item, you have found an N+1 shape. If it scans a large list repeatedly, build an index or push the work into the database.

Key takeaways

  • Data structures are operation trade-offs: lookup, insert, order, traversal, memory.
  • Big O tells you how work grows; real systems also care about constants, disk, and network.
  • Maps and sets eliminate many accidental nested loops.
  • Graphs are not rare; dependencies, routes, workflows, and social edges are all graphs.
  • Before optimizing, name the input size and the operation that grows with it.

Checkpoint questions

Use these to test whether the lesson is clear enough to explain without rereading.

  1. 1Which operation makes an array, map, set, queue, tree, or graph the right choice?
  2. 2What does Big O ignore, and when can constant factors still dominate?
  3. 3How would you choose a data structure for membership checks, ordered traversal, or shortest paths?
  4. 4What input size would make an apparently simple nested loop risky?

References

External resources for going deeper after the lesson above.