Algorithms: A Guide to Fundamental and Advanced Techniques
This section covers the most important areas of algorithms: mathematical algorithms, data structures, sorting, recursion, dynamic programming, graphs, and advanced techniques. The material is intended for high school students, competitive programmers, and anyone who wants a deeper understanding of algorithmic principles.
What You Can Expect from This Tutorial
The tutorial is structured to gradually guide you from basic concepts to advanced techniques. Each subsection includes:
- Theory — clear explanations of key concepts and complexity analysis (time and memory).
- Illustrated examples — small step-by-step examples showing how an algorithm works.
- Implementations — ready-to-use code (pseudocode, Python / C++ / Java) that can be tested and modified.
- Practice problems — tasks of varying difficulty with commented solutions and optimizations.
- Tips & usage — when to use a specific approach, common mistakes, and optimization techniques.
Note: some topics (especially advanced topics and full coverage of graphs and trees) are planned but not yet fully implemented — they will be added gradually.
Mathematical Algorithms
- Introduction to Mathematical Algorithms
- Fibonacci Sequence
- Prime Numbers and Factorization
- Euclidean Algorithm (GCD)
- Fast Exponentiation
Data Structures
Sorting
Recursion and Dynamic Programming
- Recursion — Introductory Lessons
- Tower of Hanoi
- DP Fibonacci
- Knapsack Problem
- Longest Common Subsequence (LCS)
Graphs and Trees
- Introduction to Graphs
- BFS and DFS (in Serbian)
- Trees and Hierarchies (in Serbian)
- Dijkstra’s Algorithm (in Serbian)
- Minimum Spanning Tree (MST) (in Serbian)
Advanced Techniques
- Binary Search on the Answer (in Serbian)
- Two Pointers Technique (in Serbian)
- Prefix and Suffix Arrays (in Serbian)
- Fenwick Tree (Binary Indexed Tree) (in Serbian)
- Segment Tree (in Serbian)
Quick Examples (To Get the Big Picture)
Below are two short, concrete examples with explanations and implementations, so you can immediately see how theory is applied in practice:
Example 1 — Euclidean Algorithm for Greatest Common Divisor (GCD)
Idea: GCD(a, b) = GCD(b, a % b). The algorithm is simple, converges quickly, and works in O(log min(a, b)).
// Pseudocode (Python-style)
def gcd(a, b):
while b != 0:
a, b = b, a % b
return a
# Example: gcd(48, 18) -> 6
Example 2 — DFS (Graph Traversal) and Counting Connected Components
Idea: use recursion or an explicit stack to visit all nodes in a component. Time complexity is O(N + M) for a graph with N vertices and M edges.
// Pseudocode (Python-style)
# graph represented as adjacency list: graph[v] = [neighbors]
visited = set()
def dfs(v):
stack = [v]
while stack:
x = stack.pop()
if x in visited:
continue
visited.add(x)
for nei in graph[x]:
if nei not in visited:
stack.append(nei)
# Count connected components
count = 0
for v in all_vertices:
if v not in visited:
dfs(v)
count += 1
If you want, I can add more examples (e.g. Merge Sort, Dijkstra, DP strategies), or prepare problem sets with solutions for each subsection.
