# Learn Data Structures and Algorithms

December 28, 2016

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.

# Why algorithms?

This section introduces the concept of algorithms, and defines what it means when we talk about an algorithm’s *efficiency*.

# Your first algorithms!

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
- Recursion
- Binary search: Video tutorial, code and extensions
- Hands-on: Implementing Binary Search

# Sorting algorithms

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

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)

# Graph Algorithms

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)