Skip to content

Introduction to Algorithms

An algorithm is a finite sequence of well-defined instructions that takes an input and produces an Output. This definition is deceptively simple. In practice, the gap between “an algorithm that Produces the correct answer” and “an algorithm that produces the correct answer fast enough to Matter” is where most of the engineering happens.

Every system you build, maintain, or debug is a composition of algorithms: the B-tree index your Database uses to serve a query, the congestion control algorithm in TCP that decides how fast your Service can send data, the load balancing algorithm that distributes requests across your fleet, the Garbage collector that reclaims memory in your runtime. Understanding these algorithms at a deep Level is what separates engineers who can diagnose a latency regression from engineers who can only Reboot the service.

Data structures and algorithms are inseparable. A data structure is a particular way of organising Data in memory; an algorithm is a sequence of operations on that data. Choosing the wrong data Structure makes the best algorithm slow, and choosing the right data structure can make a naive Algorithm fast enough.

graph LR
    A[Data Structures] --> B[Arrays / Strings]
    A --> C[Linked Lists]
    A --> D[Stacks / Queues]
    A --> E[Trees / Heaps]
    A --> F[Graphs]
    A --> G[Hash Tables]
    H[Algorithms] --> I[Sorting]
    H --> J[Searching]
    H --> K[Graph Traversal]
    H --> L[Dynamic Programming]
    H --> M[Greedy / Backtracking]
    B -.-> I
    G -.-> J
    F -.-> K
    D -.-> L

The relationship is not one-to-one. A hash table can implement a set or a map. A balanced BST can do The same. Which one you choose depends on whether you need ordered iteration, worst-case guarantees, Or amortised constant-time operations. These trade-offs are the substance of systems engineering.

This subject assumes familiarity with:

  • LogarithmsO(logn)O(\log n) is the most important complexity class you will encounter. You need to be comfortable with the algebraic identities: log(ab)=loga+logb\log(ab) = \log a + \log b log(ab)=bloga\log(a^b) = b \log a, and the change of base formula.
  • Summations — Many algorithm analyses reduce to evaluating sums. Know the closed forms for i=1ni=n(n+1)/2\sum_{i=1}^{n} i = n(n+1)/2, i=1ni2=n(n+1)(2n+1)/6\sum_{i=1}^{n} i^2 = n(n+1)(2n+1)/6And the geometric series i=0kri=(rk+11)/(r1)\sum_{i=0}^{k} r^i = (r^{k+1} - 1)/(r - 1).
  • Recurrence relations — Divide-and-conquer algorithms produce recurrences like $T(n) = 2T(n/2)
  • O(n)$. The Master Theorem provides closed-form solutions for a broad class of these.
  • Proof techniques — Induction, contradiction, and construction are used throughout to prove correctness and bounds.
ChapterFocusKey Algorithms
Complexity AnalysisAsymptotic notation, Master Theorem, amortised analysis, NP-completeness
Arrays and StringsTwo pointers, sliding window, prefix sums, hashing, string matchingRabin-Karp, KMP
Linked Lists, Stacks, QueuesLinear structures, monotonic structures, union-findFloyd”s cycle detection
Trees and GraphsBSTs, balanced trees, heaps, tries, graph traversal, topological sortBFS, DFS
SortingComparison and non-comparison sorting, stability, adaptive behaviourMerge sort, quicksort, radix sort
Dynamic ProgrammingMemoisation, tabulation, state space reduction, common DP patternsKnapsack, LCS, edit distance
Graph AlgorithmsShortest paths, MSTs, network flow, strong connectivityDijkstra, Kruskal, Ford-Fulkerson

These notes are written for systems engineers who need to understand algorithms at the level Required to make informed design decisions — not just pass an interview. Each chapter includes Complexity analysis, practical implementation considerations, and a “Common Pitfalls” section drawn From real production failures.

Read the chapters in order if you are building foundational knowledge. Use them as reference Material if you are looking up a specific algorithm or trying to understand why a particular data Structure is the wrong choice for your workload.

Algorithms are step-by-step recipes for solving problems. The key question is efficiency: how fast does the solution scale as input grows? Big O notation describes this: O(n) means the time grows linearly, O(n^2) means it grows quadratically. Think of algorithms as travel routes: a direct flight (O(1) lookup) is better than driving through every city (O(n) scan). Choosing the right algorithm for the job is the difference between a program that runs in milliseconds and one that runs for days.