Competitive Programming in Python Handbook
Competitive Programming in Python Handbook
Certainly! Below is a concise handbook that covers frequently used algorithms and data structures in
competitive programming, with explanations and Python implementations.
## Table of Contents
1. Introduction
2. Data Structures
- Arrays
- Linked Lists
- Stacks
- Queues
- Trees
- Graphs
- Hash Tables
3. Algorithms
- Sorting Algorithms
- Searching Algorithms
- Dynamic Programming
- Greedy Algorithms
- Graph Algorithms
- String Algorithms
4. Conclusion
---
## 1. Introduction
Competitive programming requires a solid understanding of algorithms and data structures to solve
problems efficiently. This handbook provides an overview of the most commonly used structures and
algorithms, along with Python implementations.
---
## 2. Data Structures
### Arrays
A collection of elements identified by index. Used for storing data in contiguous memory locations.
**Python Example:**
```python
arr = [1, 2, 3, 4, 5]
print(arr[2]) # Output: 3
```
A data structure consisting of nodes, where each node contains data and a reference to the next node.
**Python Example:**
```python
class Node:
self.value = value
self.next = None
class LinkedList:
def __init__(self):
self.head = None
```
### Stacks
A collection of elements that follows Last In First Out (LIFO) principle. Supports `push` and `pop`
operations.
**Python Example:**
```python
stack = []
stack.append(1)
stack.append(2)
print(stack.pop()) # Output: 2
```
### Queues
A collection of elements that follows First In First Out (FIFO) principle. Supports `enqueue` and
`dequeue` operations.
**Python Example:**
```python
queue = deque()
queue.append(1)
queue.append(2)
print(queue.popleft()) # Output: 1
```
### Trees
A hierarchical data structure with nodes connected by edges. Each tree has a root and can have children.
```python
class TreeNode:
self.value = value
self.left = None
self.right = None
```
### Graphs
```python
graph = {
0: [1, 2],
1: [2],
2: [0, 3],
3: [3]
```
A data structure that maps keys to values for efficient lookups, insertions, and deletions.
**Python Example:**
```python
hash_table = {}
hash_table['key'] = 'value'
```
---
## 3. Algorithms
1. **Bubble Sort**: Repeatedly swap adjacent elements if they are in the wrong order.
3. **Merge Sort**: Divide the array into halves, sort and merge.
```python
def merge_sort(arr):
if len(arr) > 1:
mid = len(arr) // 2
left_half = arr[:mid]
right_half = arr[mid:]
merge_sort(left_half)
merge_sort(right_half)
i=j=k=0
i += 1
else:
arr[k] = right_half[j]
j += 1
k += 1
arr[k] = left_half[i]
i += 1
k += 1
arr[k] = right_half[j]
j += 1
k += 1
# Example usage:
merge_sort(arr)
```
```python
def binary_search(arr, target):
if arr[mid] == target:
return mid
left = mid + 1
else:
right = mid - 1
return -1
# Example usage:
arr = [1, 2, 3, 4, 5]
```
A method for solving complex problems by breaking them down into simpler subproblems, storing
results to avoid recomputation.
```python
def fibonacci(n):
dp = [0] * (n + 1)
dp[1] = 1
return dp[n]
# Example usage:
print(fibonacci(10)) # Output: 55
```
A method for solving problems by making a sequence of choices, each of which looks best at the
moment.
```python
n = len(start)
count = 1
last_finish_time = activities[0][1]
count += 1
last_finish_time = activities[i][1]
return count
# Example usage:
start = [1, 3, 0, 5, 8, 5]
finish = [2, 4, 6, 7, 9, 9]
```
### Graph Algorithms
1. **Depth First Search (DFS)**: Traverses the graph by exploring as far as possible along each branch.
2. **Breadth First Search (BFS)**: Explores all neighbors at the present depth prior to moving on to
nodes at the next depth level.
3. **Dijkstra’s Algorithm**: Finds the shortest path from a source to all vertices in a weighted graph.
```python
visited = set()
queue = deque([start])
visited.add(start)
while queue:
vertex = queue.popleft()
visited.add(neighbor)
queue.append(neighbor)
# Example usage:
graph = {
0: [1, 2],
1: [0, 3, 4],
2: [0],
3: [1],
4: [1]
bfs(graph, 0) # Output: 0 1 2 3 4
```
```python
compute_lps_array(pattern, lps)
if pattern[j] == text[i]:
i += 1
j += 1
if j == len(pattern):
j = lps[j - 1]
if j != 0:
j = lps[j - 1]
else:
i += 1
length = 0
i=1
if pattern[i] == pattern[length]:
length += 1
lps[i] = length
i += 1
else:
if length != 0:
length = lps[length - 1]
else:
lps[i] = 0
i += 1
# Example usage:
text = "ABABDABACDABABCABAB"
pattern = "ABABCABAB"
```
---
## 4. Conclusion
This handbook provides a solid foundation for understanding the data structures and algorithms
commonly used in competitive programming. Mastering these concepts will significantly improve your
problem-solving skills and performance in contests.
Feel free to expand upon this handbook with more advanced topics or additional algorithms based on
your needs!
Great! Here’s a more detailed version of the competitive programming handbook, expanding on the
previous sections and including more advanced topics and algorithms.
## Table of Contents
1. Introduction
2. Data Structures
- Arrays
- Linked Lists
- Stacks
- Queues
- Trees
- Binary Trees
- Heaps
- Segment Trees
- Graphs
- Hash Tables
3. Algorithms
- Sorting Algorithms
- Searching Algorithms
- Dynamic Programming
- Greedy Algorithms
- Graph Algorithms
- String Algorithms
- Number Theory
- Combinatorial Algorithms
4. Conclusion
---
## 1. Introduction
Competitive programming is a mental sport that involves solving algorithmic and mathematical problems
within a limited time frame. This handbook aims to equip you with the essential data structures and
algorithms frequently encountered in contests.
---
## 2. Data Structures
### Arrays
**Example**:
```python
arr = [1, 2, 3, 4, 5]
print(arr[2]) # Output: 3
```
- **Definition**: A linear data structure where elements are stored in nodes, with each node containing
a reference to the next.
- **Types**: Singly Linked List, Doubly Linked List, Circular Linked List.
**Example**:
```python
class Node:
self.value = value
self.next = None
class LinkedList:
def __init__(self):
self.head = None
new_node = Node(value)
if not self.head:
self.head = new_node
return
last = self.head
while last.next:
last = last.next
last.next = new_node
```
### Stacks
**Example**:
```python
stack = []
stack.append(1)
stack.append(2)
print(stack.pop()) # Output: 2
```
### Queues
**Example**:
```python
queue = deque()
queue.append(1)
queue.append(2)
print(queue.popleft()) # Output: 1
```
### Trees
```python
class TreeNode:
self.value = value
self.left = None
self.right = None
```
- **Definition**: A binary tree where for each node, the left child’s value is less, and the right child’s
value is greater.
**Insertion Example**:
```python
class BST:
def __init__(self):
self.root = None
if not self.root:
self.root = TreeNode(value)
else:
self._insert_recursive(self.root, value)
if node.left is None:
node.left = TreeNode(value)
else:
self._insert_recursive(node.left, value)
else:
if node.right is None:
node.right = TreeNode(value)
else:
self._insert_recursive(node.right, value)
```
#### Heaps
- **Definition**: A complete binary tree that maintains the heap property (max-heap or min-heap).
**Example (Min-Heap)**:
```python
import heapq
min_heap = []
heapq.heappush(min_heap, 5)
heapq.heappush(min_heap, 3)
print(heapq.heappop(min_heap)) # Output: 3
```
- **Definition**: A tree used for storing intervals or segments, allowing efficient range queries and
updates.
class SegmentTree:
self.n = len(data)
for i in range(self.n):
self.tree[self.n + i] = data[i]
idx += self.n
self.tree[idx] = value
idx >>= 1
result = 0
left += self.n
right += self.n
if left & 1:
result += self.tree[left]
left += 1
if right & 1:
right -= 1
result += self.tree[right]
left >>= 1
right >>= 1
return result
# Example usage:
seg_tree = SegmentTree(data)
```
- **Definition**: A data structure that provides efficient methods for cumulative frequency tables and
point updates.
**Example**:
```python
class FenwickTree:
self.size = size
self.tree[index] += delta
sum = 0
sum += self.tree[index]
index -= index & -index
return sum
# Example usage:
fenwick = FenwickTree(10)
fenwick.update(1, 5)
fenwick.update(2, 3)
print(fenwick.query(2)) # Output: 8
```
### Graphs
#### Representations:
1. **Adjacency List**:
```python
graph = {
0: [1, 2],
1: [2],
2: [0, 3],
3: [3]
```
2. **Adjacency Matrix**:
```python
n=4
adj_matrix[0][1] = 1
adj_matrix[0][2] = 1
```
---
## 3. Algorithms
```python
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
# Example usage:
```
### Searching Algorithms
```python
if arr[mid] == target:
return mid
left = mid + 1
else:
right = mid - 1
return -1
# Example usage:
arr = [1, 2, 3, 4, 5]
```
- **Definition**: A method to solve problems by breaking them into simpler subproblems and storing
their solutions.
**Fibonacci Example**:
```python
def fibonacci(n):
if n <= 1:
return n
dp = [0] * (n + 1)
dp[1] = 1
for i in range(2, n
+ 1):
return dp[n]
# Example usage:
print(fibonacci(10)) # Output: 55
```
- **Definition**: A method for solving optimization problems by selecting the best option at each step.
```python
count = 1
last_finish_time = activities[0][1]
count += 1
last_finish_time = activities[i][1]
return count
# Example usage:
start = [1, 3, 0, 5, 8, 5]
finish = [2, 4, 6, 7, 9, 9]
```
```python
if visited is None:
visited = set()
visited.add(start)
return visited
# Example usage:
graph = {
0: [1, 2],
1: [0, 3],
2: [0],
3: [1]
```python
visited = set()
queue = deque([start])
visited.add(start)
while queue:
vertex = queue.popleft()
visited.add(neighbor)
queue.append(neighbor)
# Example usage:
bfs(graph, 0) # Output: 0 1 2 3
```
3. **Dijkstra’s Algorithm**:
```python
import heapq
queue = []
distances = {vertex: float('infinity') for vertex in graph}
distances[start] = 0
while queue:
continue
distances[neighbor] = distance
return distances
# Example usage:
graph = {
```
**Example (KMP)**:
```python
lps = compute_lps(pattern)
if pattern[j] == text[i]:
i += 1
j += 1
if j == len(pattern):
j = lps[j - 1]
if j != 0:
j = lps[j - 1]
else:
i += 1
def compute_lps(pattern):
length = 0
i=1
if pattern[i] == pattern[length]:
length += 1
lps[i] = length
i += 1
else:
if length != 0:
length = lps[length - 1]
else:
lps[i] = 0
i += 1
return lps
# Example usage:
text = "ABABDABACDABABCABAB"
pattern = "ABABCABAB"
```
```python
while b:
a, b = b, a % b
return a
# Example usage:
```
2. **Prime Factorization**:
```python
def prime_factors(n):
factors = []
while n % i == 0:
factors.append(i)
n //= i
if n > 1:
factors.append(n)
return factors
# Example usage:
```
1. **Permutations**:
```python
def get_permutations(elements):
return list(permutations(elements))
# Example usage:
print(get_permutations([1, 2, 3])) # Output: [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]
```
2. **Combinations**:
```python
# Example usage:
print(get_combinations([1, 2, 3, 4], 2)) # Output: [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]
```
---
## 4. Conclusion
This expanded handbook provides a comprehensive overview of essential data structures and algorithms
commonly used in competitive programming. Mastery of these topics will greatly enhance your
problem-solving abilities and performance in coding contests. Practice implementing these concepts and
tackling a variety of problems to solidify your understanding!
Feel free to adapt or expand upon this handbook based on your own experiences and needs! If you need
further details or specific topics, let me know!