Learning algorithms is difficult not only because the topics are hard, but also because beginners often do not know what topics exist in the first place.
When the landscape is unclear, it is hard to decide what to study first, what to postpone, and how one topic prepares the way for another.
This article gives a learning-ordered overview of core algorithm topics. It does not try to explain every topic fully. Instead, it gives each topic a short purpose, so the reader can understand why the topic matters and when it becomes useful.
The order is based on learning progression, not on a strict taxonomy of algorithm topics. Some families appear more than once. For example, graph topics appear first as basic representation and traversal, then later as shortest paths, connectivity, and spanning trees. Dynamic programming also appears first as a basic idea, then later as more advanced forms.
The Learning Order at a Glance
The first step is to learn the basic language of algorithms. This includes input size, time complexity, space complexity, and Big-O notation.
The second step is to learn basic data structures. Algorithms do not work on abstract data alone. They work on arrays, stacks, queues, hash maps, heaps, trees, and other structures.
The third step is to study sorting and searching. These are early examples of how a simple problem can have many different algorithmic solutions.
The fourth step is to understand recursion and search space. Many later topics, including backtracking and dynamic programming, become easier once the idea of exploring possible states is clear.
The fifth step is to learn basic graph representation and traversal. Graphs are one of the most important ways to model relationships.
The sixth step is to learn common algorithm design strategies. Greedy, divide and conquer, and dynamic programming are not just algorithms. They are ways of thinking.
The seventh step is to learn sequence techniques such as prefix sum, two pointers, and sliding window. These techniques appear often in array and string problems.
The eighth step is to study basic dynamic programming. At this stage, the goal is to understand states, transitions, memoization, and tabulation.
The ninth step is to study shortest path algorithms. These topics build on graph traversal and weighted graphs.
The tenth step is to study connectivity and spanning trees. This is where Union-Find, Kruskal, Prim, and minimum spanning trees fit naturally.
The eleventh step is to study range query structures. These structures are useful when many queries and updates must be handled efficiently.
The twelfth step is to return to dynamic programming in a deeper form. Tree DP, bitmask DP, and interval DP become more approachable after the earlier topics are already familiar.
The thirteenth step is to study string algorithms. Strings have their own structures, such as prefixes, patterns, and repeated substrings.
The final step in this overview is to study mathematical tools for algorithms. These tools are not always needed at the beginning, but they become important in many algorithmic problems.
1. Foundations
This section gives the basic language for talking about algorithms. Before studying many specific algorithms, it helps to know how to compare them and how to reason about whether they work.
1.1 Input Size
Input size is the variable that controls how much work an algorithm has to do.
This topic comes first because algorithm analysis usually starts by asking what grows. Sometimes the input size is the number of elements in an array. Sometimes it is the number of vertices and edges in a graph.
1.2 Time Complexity
Time complexity describes how the running time of an algorithm grows as the input becomes larger.
This topic matters because two programs can both produce the correct answer but behave very differently as the input grows. Time complexity gives a way to compare algorithms without depending on one specific computer.
1.3 Space Complexity
Space complexity describes how much extra memory an algorithm needs.
This topic is important because speed is not the only cost. An algorithm may be fast but require too much memory to be practical.
1.4 Big-O Notation
Big-O notation describes the growth rate of an algorithm in a simplified way.
It helps the reader focus on the main pattern of growth rather than exact timing. For example, it lets us distinguish linear growth, logarithmic growth, and quadratic growth.
1.5 Correctness
Correctness means that an algorithm always produces the intended result for valid inputs.
This topic matters because an algorithm is not useful merely because it is fast. It must also be clear why the steps actually lead to the right answer.
1.6 Loop Invariant
A loop invariant is a condition that remains true before and after each loop iteration.
It is useful because many algorithms are built from loops. A loop invariant gives a way to explain why a loop is doing the right thing step by step.
2. Basic Data Structures
Algorithms usually depend on how data is stored and accessed. This section introduces the structures that appear repeatedly in later topics.
2.1 Array
An array stores elements in a sequence and allows access by index.
It is worth studying early because many algorithms begin with arrays. Sorting, searching, prefix sums, two pointers, and dynamic programming often start from this structure.
2.2 Linked List
A linked list stores elements as nodes connected by references.
It helps the reader see that a sequence does not always have to be stored in contiguous indexed form. It also introduces the idea of pointer-like links between objects.
2.3 Stack
A stack is a last-in, first-out structure.
It is useful for understanding recursion, DFS, expression parsing, and backtracking. The most recent item is handled first.
2.4 Queue
A queue is a first-in, first-out structure.
It is important because BFS depends on this behavior. The earliest discovered item is processed before later ones.
2.5 Hash Map
A hash map stores values by key and supports fast lookup in typical cases.
This topic appears early because many algorithms need to count, group, or find values quickly. It is often the simplest way to avoid repeated scanning.
2.6 Hash Set
A hash set stores unique values and supports fast membership checks in typical cases.
It is useful when the algorithm only needs to know whether something has already appeared. Visited sets in graph traversal are a common example.
2.7 Heap
A heap keeps access to the smallest or largest value efficient.
This topic prepares the reader for priority queues. It also appears in scheduling, top-k problems, and shortest path algorithms.
2.8 Priority Queue
A priority queue removes items by priority rather than insertion order.
It matters because some algorithms need to repeatedly process the currently best candidate. Dijkstra’s algorithm is a major example.
2.9 Tree
A tree represents hierarchical structure.
It is useful before studying more advanced topics because many problems involve parent-child relationships. Recursion also becomes natural on trees.
3. Sorting and Searching
Sorting and searching are often the first place where algorithmic thinking becomes visible. They show that the same problem can be solved in simple, inefficient ways or in more structured, efficient ways.
3.1 Linear Search
Linear search checks elements one by one until the target is found.
It is worth studying because it is the simplest baseline. Many better algorithms can be understood as ways to avoid this full scan.
3.2 Binary Search
Binary search repeatedly cuts a sorted search space in half.
It is important because it teaches the idea of reducing the problem space instead of checking every element. It also appears later in many problems that are not obviously search problems at first.
3.3 Sorting
Sorting rearranges data into a useful order.
This topic matters because many algorithms become easier after sorting. Greedy algorithms, two pointers, and binary search often depend on sorted data.
3.4 Insertion Sort
Insertion sort builds a sorted region one element at a time.
It is useful as an early sorting algorithm because its behavior is easy to visualize. It also shows how a simple algorithm can be efficient for small or nearly sorted inputs.
3.5 Merge Sort
Merge sort divides the input, sorts each part, and merges the results.
It is worth studying because it is a clear example of divide and conquer. It also gives a predictable O(n log n) sorting pattern.
3.6 Quick Sort
Quick sort partitions data around a pivot.
It matters because it shows how the choice of strategy can affect average and worst-case behavior. It is also a useful example of recursive partitioning.
3.7 Counting Sort
Counting sort uses value counts instead of comparisons.
This topic can come after basic comparison sorting because it shows that sorting has different models. It works well only when the value range is suitable.
4. Recursion and Search Space
Many algorithms explore smaller subproblems or possible choices. This section prepares the reader for backtracking, graph traversal, and dynamic programming.
4.1 Recursion
Recursion solves a problem by reducing it to smaller versions of itself.
It is important because many algorithmic ideas are naturally recursive. Trees, DFS, divide and conquer, and dynamic programming all become easier with recursion.
4.2 Brute Force
Brute force tries all possible cases directly.
It is worth studying because it gives a baseline solution. More advanced algorithms can often be understood as optimized versions of brute force.
4.3 Search Space
Search space is the set of all possible states, choices, or candidates an algorithm may explore.
This topic matters because many algorithms are about controlling the size of that space. Backtracking prunes it, dynamic programming reuses it, and greedy algorithms avoid exploring much of it.
4.4 Backtracking
Backtracking explores possible choices and returns when a path cannot lead to a valid answer.
It is useful for problems involving combinations, permutations, constraints, and decision trees. It teaches the habit of searching while cutting off impossible branches.
4.5 State
A state is the information needed to describe one point in a computation.
This topic is important because states appear in search, dynamic programming, graph traversal, and shortest path algorithms. Understanding state makes later algorithms much easier to organize.
5. Graph Representation and Traversal (Basic)
Graphs model relationships. This section introduces graphs only at the level needed for basic traversal.
5.1 Graph
A graph is a structure made of vertices and edges.
It is useful because many problems can be rephrased as relationships between objects. Roads, dependencies, networks, and game states can all be represented as graphs.
5.2 Vertex and Edge
A vertex represents an object, and an edge represents a relationship or movement between objects.
These are the basic parts of a graph. Without these two concepts, graph algorithms have no clear language.
5.3 Directed and Undirected Graphs
A directed graph has edges with direction, while an undirected graph has edges that work both ways.
This distinction matters because traversal and reachability can change completely depending on edge direction. A one-way relationship is not the same as a two-way relationship.
5.4 Weighted Graph
A weighted graph attaches a cost or value to each edge.
This topic prepares the reader for shortest path algorithms. BFS works naturally when all edges have the same cost, but weighted graphs require different tools.
5.5 Adjacency List
An adjacency list stores each vertex with the vertices connected to it.
It is usually the most practical graph representation for sparse graphs. It also makes BFS and DFS easier to implement.
5.6 Adjacency Matrix
An adjacency matrix stores whether each pair of vertices is connected.
It is useful when quick edge lookup is important or when the graph is dense. It also helps the reader see that the same graph can be represented in different ways.
5.7 BFS
BFS visits nodes in increasing distance from the starting point.
It is worth studying early because it uses a queue and gives a simple model of layer-by-layer exploration. It also becomes the shortest path algorithm for unweighted graphs.
5.8 DFS
DFS explores deeply along one path before returning to other choices.
It is important because it connects graph traversal with recursion and stacks. DFS also appears in cycle detection, topological sort, and backtracking-like graph problems.
5.9 Visited Set
A visited set records which nodes have already been processed or discovered.
This topic matters because graphs can contain cycles. Without a visited set, traversal can repeat work or even fail to terminate.
5.10 Connected Components
Connected components are separate groups of vertices connected within themselves.
This topic is useful because it shows how traversal can classify an entire graph, not just visit from one starting point. BFS or DFS can be used to find these groups.
5.11 Cycle Detection
Cycle detection asks whether a graph contains a loop.
It matters because cycles affect whether certain algorithms are valid. For example, topological sorting only works on directed acyclic graphs.
5.12 Topological Sort
Topological sort orders vertices when some must come before others.
It is useful for dependency problems, build orders, course prerequisites, and directed acyclic graphs. It should come after basic DFS or indegree-based traversal is familiar.
6. Algorithm Design Strategies (Basic)
This section introduces common ways of thinking. These strategies are not only individual techniques. They are reusable mental models.
6.1 Divide and Conquer
Divide and conquer breaks a problem into smaller parts and combines their results.
This topic comes naturally after recursion and merge sort. It teaches the idea that a large problem can sometimes be solved by solving smaller independent problems.
6.2 Greedy
A greedy algorithm makes the best-looking local choice at each step.
It is important because many efficient algorithms use this idea. However, greedy choices only work when the problem has the right structure, so this topic also teaches caution.
6.3 Dynamic Programming as an Idea
Dynamic programming solves problems by reusing answers to overlapping subproblems.
At this stage, the goal is only to understand the idea. The detailed techniques come later, after the reader is comfortable with recursion, states, and repeated subproblems.
7. Sequence Techniques (Basic to Intermediate)
Many array and string problems become easier when the right movement pattern is used. These techniques are often simpler than full dynamic programming but more powerful than brute force.
7.1 Prefix Sum
Prefix sum stores cumulative totals so range sums can be answered quickly.
It is useful because it turns repeated range calculations into simple subtraction. This is often one of the first preprocessing techniques worth learning.
7.2 Difference Array
A difference array makes repeated range updates efficient.
It is useful after prefix sum because it is based on a related idea. Instead of storing all final values directly, it stores changes that can later be accumulated.
7.3 Two Pointers
Two pointers use two moving positions to control a search or interval.
This technique is useful after sorting and arrays are familiar. It often replaces nested loops with a more efficient linear scan.
7.4 Sliding Window
Sliding window maintains information about a moving contiguous range.
It is useful for problems about subarrays or substrings. The key idea is to update the current window instead of recomputing from scratch.
7.5 Monotonic Stack
A monotonic stack keeps elements in a controlled increasing or decreasing order.
It is useful for nearest-greater, nearest-smaller, and span-like problems. This topic should come after the basic stack is already comfortable.
7.6 Monotonic Queue
A monotonic queue keeps a window ordered enough to answer minimum or maximum queries efficiently.
It is useful for sliding window maximum or minimum problems. It is more advanced than a normal queue because it maintains both order of arrival and useful value order.
8. Dynamic Programming (Basic)
Dynamic programming becomes easier when it is seen as controlled reuse of states. This section focuses on the first DP ideas a beginner should learn.
8.1 Overlapping Subproblems
Overlapping subproblems occur when the same smaller problem appears repeatedly.
This concept is the reason dynamic programming is useful. Without repeated subproblems, storing previous answers may not help much.
8.2 Recurrence
A recurrence describes how a solution depends on smaller solutions.
This topic is central because DP is not just storage. The reader must first know how one state gets its value from earlier states.
8.3 Memoization
Memoization stores the results of recursive calls.
It is useful because it keeps the recursive structure while avoiding repeated work. This is often the easiest entry point into dynamic programming.
8.4 Tabulation
Tabulation fills a table from smaller states to larger states.
It is useful because it makes the order of computation explicit. Many iterative DP solutions are written this way.
8.5 1D Dynamic Programming
1D DP uses one main variable to describe the state.
It is a good first practical form of DP. Problems like climbing stairs or simple sequence decisions can often be expressed this way.
8.6 2D Dynamic Programming
2D DP uses two variables to describe the state.
This topic should come after 1D DP because the table becomes larger and the transitions become more complex. Grid problems and string comparison problems often use this form.
8.7 Knapsack
Knapsack problems ask how to choose items under a limited capacity.
This topic is important because it teaches choice-based DP. It also shows how state can represent both position and remaining capacity.
8.8 Grid DP
Grid DP solves path, counting, or optimization problems on a grid.
It is useful because the state is easy to visualize. Each cell often depends on nearby cells, which makes transitions easier to understand.
8.9 Longest Increasing Subsequence
Longest increasing subsequence asks for the longest ordered subsequence that keeps increasing values.
It is worth studying because it shows that DP can be applied to sequence structure. It also has both a basic DP solution and a more advanced binary-search-based solution.
9. Shortest Path Algorithms (Intermediate)
Shortest path problems ask how to move through a graph with minimum cost. This section should come after basic graph traversal and weighted graphs.
9.1 BFS Shortest Path
BFS finds shortest paths when every edge has the same cost.
This topic connects basic BFS to shortest path thinking. It shows that graph traversal can also solve optimization problems under the right conditions.
9.2 DAG Shortest Path
DAG shortest path uses topological order in a directed acyclic graph.
It is useful because it shows how graph structure can simplify a shortest path problem. When there are no directed cycles, vertices can be processed in a safe order.
9.3 Dijkstra
Dijkstra’s algorithm finds shortest paths from one starting vertex when edge weights are non-negative.
It is important because it combines graphs, greedy thinking, and priority queues. It should come after the reader understands weighted graphs and priority queues.
9.4 Bellman-Ford
Bellman-Ford finds shortest paths even when negative edge weights exist.
It is useful because it explains a limitation of Dijkstra. It also introduces the idea of repeatedly relaxing edges.
9.5 Floyd-Warshall
Floyd-Warshall finds shortest paths between every pair of vertices.
It is useful when the graph is not too large and all-pairs distances are needed. It also gives a clear example of dynamic programming on graph paths.
9.6 Path Reconstruction
Path reconstruction records enough information to recover the actual route, not just the distance.
This topic matters because many shortest path problems ask for the path itself. Distances alone do not always answer the full problem.
10. Connectivity and Spanning Trees (Intermediate)
Some graph problems are not mainly about visiting nodes or finding shortest paths. They are about whether things are connected and how to connect everything at minimum cost.
10.1 Disjoint Set
A disjoint set represents groups that do not overlap.
This concept prepares the reader for Union-Find. It is useful when the algorithm needs to manage changing groups.
10.2 Union-Find
Union-Find supports two main operations: finding which group an element belongs to and merging two groups.
It is important because it solves connectivity questions efficiently. It is not a traversal algorithm, but it can answer whether two elements are already connected.
10.3 Path Compression
Path compression makes Union-Find faster by shortening parent chains during find operations.
This topic matters because the basic idea of Union-Find is simple, but its efficiency depends on optimization. Path compression is one of the key optimizations.
10.4 Union by Rank or Size
Union by rank or size keeps the structure shallow when merging groups.
It is useful together with path compression. The goal is to avoid long chains that would make find operations slow.
10.5 Minimum Spanning Tree
A minimum spanning tree connects all vertices with the minimum total edge cost.
This topic is different from shortest path. It is about connecting the whole graph cheaply, not about finding the cheapest route from one vertex to another.
10.6 Kruskal
Kruskal’s algorithm builds a minimum spanning tree by considering edges in increasing cost order.
It is useful because it connects greedy thinking with Union-Find. Union-Find helps detect whether adding an edge would create a cycle.
10.7 Prim
Prim’s algorithm builds a minimum spanning tree by growing one connected tree outward.
It is useful as a contrast to Kruskal. Both solve the same problem, but they grow the solution in different ways.
11. Range Query Structures (Intermediate)
Range query structures become useful when many queries and updates must be answered efficiently. These topics should come after arrays, prefix sums, and basic complexity analysis.
11.1 Range Query
A range query asks for information about a section of an array.
This topic matters because many problems repeat the same kind of question over many ranges. The main challenge is to avoid scanning the range every time.
11.2 Fenwick Tree
A Fenwick tree supports efficient prefix queries and updates.
It is useful after prefix sum because it handles updates better. It is often simpler than a segment tree but more limited in what it can express.
11.3 Segment Tree
A segment tree stores information about intervals in a tree structure.
It is useful for range minimum, range maximum, range sum, and other interval queries. It is more flexible than a Fenwick tree but also more complex.
11.4 Lazy Propagation
Lazy propagation delays updates in a segment tree.
This topic matters when range updates are frequent. Instead of updating every affected element immediately, the structure records pending work and applies it when needed.
11.5 Sparse Table
A sparse table answers fixed-array range queries efficiently after preprocessing.
It is useful when the array does not change. This topic shows that different constraints lead to different data structures.
12. Dynamic Programming (Advanced)
This section returns to dynamic programming after the reader has seen graphs, trees, ranges, and more complex state spaces. These topics are easier once basic DP is already familiar.
12.1 Tree DP
Tree DP computes answers over a tree by combining child results.
It is useful because tree structure gives a natural direction for recursion. Many problems ask for the best answer within each subtree.
12.2 Bitmask DP
Bitmask DP represents sets as bits and runs dynamic programming over subsets.
It is important for problems where the state includes which elements have already been used. It is often seen in traveling-salesman-like problems or subset selection problems.
12.3 Interval DP
Interval DP solves problems where the state is a continuous range.
It is useful when the answer for a range depends on smaller ranges inside it. This topic appears in problems about merging, splitting, or parenthesizing sequences.
12.4 State Compression
State compression reduces a complex state into a smaller representation.
This topic matters because DP can become too large if the state is described naively. Bitmasks are one common form of state compression.
13. String Algorithms (Intermediate)
String algorithms deal with patterns, prefixes, and repeated structure. These topics are easier after arrays, hashing, and basic algorithm analysis are familiar.
13.1 Trie
A trie stores strings by shared prefixes.
It is useful for autocomplete, dictionary lookup, and prefix search. It also shows that strings can be stored structurally rather than as isolated values.
13.2 String Matching
String matching asks where a pattern appears inside a larger string.
This topic is important because naive matching can repeat unnecessary comparisons. More advanced algorithms use the structure of the pattern to skip work.
13.3 KMP
KMP uses prefix information to avoid restarting a search from scratch.
It is useful because it shows how preprocessing can make repeated matching efficient. It also introduces a deeper way to think about repeated structure inside strings.
13.4 Rolling Hash
Rolling hash represents substrings with hash values that can be updated efficiently.
It is useful for fast substring comparison. It should be studied with care because hash collisions are possible.
13.5 Suffix Array
A suffix array stores all suffixes of a string in sorted order.
This topic is more advanced than basic string matching. It becomes useful when many substring or lexicographic queries must be answered.
14. Math Tools for Algorithms (Basic to Intermediate)
Mathematical tools do not need to come first, but they become important in many algorithm problems. This section collects the most common tools that support algorithmic thinking.
14.1 GCD
The greatest common divisor is the largest number that divides two numbers.
It is useful because many number problems depend on divisibility. The Euclidean algorithm is also a good example of a simple and efficient recursive idea.
14.2 Modular Arithmetic
Modular arithmetic keeps only the remainder after division.
It is important because algorithm problems often involve very large numbers. Taking remainders keeps values manageable while preserving useful structure.
14.3 Fast Exponentiation
Fast exponentiation computes powers by repeatedly squaring.
It is useful because direct repeated multiplication can be too slow. This topic also shows how binary structure can reduce work.
14.4 Sieve of Eratosthenes
The Sieve of Eratosthenes finds many prime numbers efficiently.
It is useful when many primality-related queries are needed. It teaches the idea of preprocessing by eliminating impossible candidates.
14.5 Combinatorics
Combinatorics studies how to count selections, arrangements, and cases.
It is useful because many algorithms depend on counting possibilities. It also appears in dynamic programming, probability, and modular arithmetic problems.
14.6 Matrix Exponentiation
Matrix exponentiation uses matrices to compute repeated linear transitions efficiently.
This topic is more advanced and does not need to be studied early. It becomes useful when a recurrence must be applied many times.
The Main Point
A beginner does not need to master every topic at once. The first goal is to reduce the unknown landscape.
Once the major topics are visible, it becomes easier to decide what to study next. The point of this article is not to turn algorithms into a checklist, but to give the reader a first ordered map of the field.
A practical first path is to begin with complexity and basic data structures, then move to sorting, searching, recursion, graph traversal, and basic dynamic programming. After that, shortest paths, Union-Find, range query structures, advanced dynamic programming, string algorithms, and mathematical tools can be studied with much less confusion.