This 28-part course consists of tutorials on data structures and algorithms. It alternates between tutorials and implementation, and you get to implement every algorithm. You can think of this course as a “Free Online Nano Book”.
This course teaches algorithms and data structures from the ground-up. It starts with why you need algorithms, and then proceeds to teach you sorting algorithms, dynamic programming, and graph algorithms.
The primary objectives of this course are:
- Learn efficient algorithms for sorting and searching, such as merge-sort, quick-sort, and binary search.
- Learn problem solving techniques such as recursion and divide-and-conquer.
- Learn dynamic programming and solve a variety of dynamic programming problems.
- Learn data structures such as heaps and disjoint set data structure.
- Learn about graphs and graph algorithms such as graph search algorithms, shortest path algorithms, minimum spanning tree.
- Implement each of the learnt algorithms and data structures from scratch in Python, C++, Java or any other programming language of your choice.
Most of the tutorials are a combination of video, text and code! The tutorials have been edited and curated meticulously and are some of the best tutorials on each topic available online.
This section introduces the concept of algorithms, and defines what it means when we talk about an algorithm’s efficiency.
We’ll start with the greedy algorithm, and after that we’ll learn about recursion.
Binary search is a recursive search algorithm which runs in O($\log n$) time. It’s an example of a divide-and-conquer algorithm.
- Greedy Algorithm
- Binary search: Video tutorial, code and extensions
- Hands-on: Implementing Binary Search
Sorting algorithms are a set of algorithms that all solve the same problem (sorting) but using very different strategies. These algorithms will introduce you to techniques such as recursion, divide-and-conquer, heaps, etc.
- Our first sorting algorithm: Simple Sort
- Merge-sort: Detailed tutorial with Python & C++ implementation
- Hands-on: Implementing Merge-sort
- Hands-on: Counting inversions (with progressive ‘hint-by-hint’ solution)
- Quick-sort: Video tutorial, pseudo-code (and in-place sorting)
- Hands-on: Implementing Quick-sort
- Hands-on: Overlapping intervals (with progressive ‘hint-by-hint’ solution)
- Hands-on: Minimum Difference (with progressive ‘hint-by-hint’ solution)
- Heaps and Heap-sort
- Hands-on: Implementing Heaps and Heap-sort
- Hands-on: K-sort (with progressive ‘hint-by-hint’ solution)
Dynamic programming is a very versatile method, used for solving a wide variety of problems. We’ll introduce dynamic programming by applying it to a problem, and then solve a range of problems using dynamic programming.
- Dynamic Programming
- Hands-on: Tiling Problem v2.0 (with progressive ‘hint-by-hint’ solution)
- Hands-on: Paths in a Grid (with progressive ‘hint-by-hint’ solution)
- Hands-on: Longest Common Subsequence (with progressive ‘hint-by-hint’ solution)
In this section, we introduce graphs. Like dynamic programming, graphs are also very versatile. We’ll discuss graph search algorithms like breadth-first search and depth-first search, shortest path algorithms like Dijkstra, and minimum spanning tree algorithms such as Prim’s and Kruskal’s.
- Introduction to Graphs (and how to represent them)
- Breadth-first search and Depth-first search
- Hands-on: Implementing Breadth-first search
- Dijkstra’s algorithm (Shortest path algorithm)
- Hands-on: Implementing Dijkstra’s algorithm
- Prim’s algorithm for Minimum Spanning Tree
- Kruskal’s algorithm for Minimum Spanning Tree
- Hands-on: Implementing Minimum Spanning Tree algorithms (Prim’s / Kruskal’s)