Competitive Programming in Python

Author: Christoph Dürr, Jill-Jênn Vie
File Type: pdf
Size: 7.3 MB
Language: English
Pages: 264

Competitive Programming in Python: 128 Algorithms to Develop Your Coding Skills

Competitive programming is much more than writing code quickly. It is a disciplined way to transform a complex problem into a precise algorithm, implement that algorithm efficiently, and prove that the solution can handle large inputs. 🧠💻

For Python developers, competitive programming provides an excellent environment for developing algorithmic thinking, data-structure knowledge, debugging ability, and computational efficiency.

The concept behind “Competitive Programming in Python: 128 Algorithms to Develop Your Coding Skills” can be viewed as a structured journey through algorithms that gradually moves from basic programming techniques to advanced graph theory, dynamic programming, optimization, and mathematical problem solving.

Competitive Programming in Python

Image

Whether you are a university student preparing for programming contests, an engineer improving your problem-solving skills, or a professional preparing for technical interviews, learning algorithms systematically can dramatically improve your ability to design efficient software.


Introduction

A competitive programming problem often looks deceptively simple:

Given some input, calculate the correct output.

However, the real challenge is usually hidden inside the constraints.

Suppose a problem gives you 1,000,000 numbers. A solution requiring (O(n^2)) operations may become unusable, while an (O(n\log n)) solution could finish comfortably.

Python is particularly attractive because its syntax is concise and its standard library contains powerful tools such as:

  • heapq
  • bisect
  • collections
  • itertools
  • math
  • functools
  • array
  • deque

The objective is not simply to memorize 128 algorithms. Instead, the goal is to understand when an algorithm should be used, why it works, and how its complexity affects performance. ⚡

ImageImage


Background Theory

Algorithms are finite procedures for solving computational problems. An algorithm receives input, processes it according to a defined sequence of operations, and produces an output.

A useful engineering model is:

[A(I) = O]

where:

  • (A) = algorithm
  • (I) = input
  • (O) = output

But correctness alone is not enough. We also need to evaluate computational resources.

Time Complexity

Time complexity describes how execution requirements grow with input size.

Common complexity classes include:

ComplexityTypical ExampleScalability
(O(1))Array accessExcellent
(O(\log n))Binary searchExcellent
(O(n))Linear scanVery good
(O(n\log n))Efficient sortingGood
(O(n^2))Nested comparisonsLimited
(O(2^n))Subset enumerationVery limited
(O(n!))Permutation searchExtremely limited

Space Complexity

Memory requirements are equally important.

For example:

[S(n)=O(n)]

means memory usage grows approximately linearly with input size.

An algorithm that is fast but requires enormous memory may still fail.


Definition

Competitive programming in Python is the practice of solving algorithmic programming problems under constraints such as limited execution time, memory limits, and strict input/output requirements.

The 128-algorithm approach can be understood as a broad algorithmic toolkit covering several major areas:

Fundamental Algorithms

These include:

  • Linear search
  • Binary search
  • Sorting
  • Prefix sums
  • Two-pointer techniques
  • Sliding windows
  • Recursion
  • Greedy algorithms

Data Structures

Important structures include:

  • Arrays
  • Stacks
  • Queues
  • Deques
  • Hash tables
  • Sets
  • Heaps
  • Trees
  • Graphs
  • Disjoint-set structures

Graph Algorithms

Typical graph techniques include:

  • Breadth-first search
  • Depth-first search
  • Dijkstra’s algorithm
  • Bellman-Ford
  • Floyd-Warshall
  • Topological sorting
  • Minimum spanning trees
  • Union-Find

Dynamic Programming

Dynamic programming is particularly important for difficult problems involving overlapping subproblems.

Common patterns include:

[DP[i]=\min(DP[i-1]+c_i,;DP[i-2]+c_{i-1})]

The exact recurrence depends on the problem, but the fundamental concept remains the same: store useful previous results instead of recomputing them.


Step-by-Step Explanation: How to Solve a Competitive Programming Problem

The most effective approach is not to immediately start writing Python code.

Step 1 — Read the Constraints

Look carefully at:

[1\leq n\leq10^5]

A value such as (10^5) immediately tells you that an (O(n^2)) algorithm is probably inappropriate.

Step 2 — Understand the Input

Determine:

  • How many test cases exist?
  • What are the data types?
  • Is the data sorted?
  • Can duplicate values occur?
  • Are negative values possible?

Step 3 — Identify the Pattern

Ask whether the problem resembles:

  • Searching
  • Sorting
  • Prefix sums
  • Graph traversal
  • Dynamic programming
  • Greedy optimization
  • Backtracking
  • Number theory

Step 4 — Develop the Algorithm

Before coding, write the logic in plain language.

For example:

  1. Sort the array.
  2. Select the smallest unused element.
  3. Maintain the current answer.
  4. Continue until all elements are processed.

Step 5 — Estimate Complexity

If your algorithm contains:

for every element:
    search through every other element

you probably have:

[O(n^2)]

If sorting dominates:

[O(n\log n)]

Step 6 — Implement in Python

A concise implementation might look like:

numbers = sorted(map(int, input().split()))

answer = 0

for x in numbers:
    answer += x

print(answer)

Step 7 — Test Edge Cases

Always test:

  • Empty or minimal input
  • One element
  • Duplicate values
  • Negative values
  • Very large values
  • Already sorted input
  • Reverse-sorted input

ImageImage

Image

Image

Image


Comparison: Brute Force vs Optimized Algorithms

One of the most important lessons in competitive programming is recognizing when a straightforward approach is too slow.

ApproachTypical ComplexityAdvantageDisadvantage
Brute force(O(n^2)) or worseEasy to understandPoor scalability
Sorting(O(n\log n))Simple and powerfulChanges ordering
HashingAverage (O(n))Fast lookupAdditional memory
Binary search(O(\log n))Extremely efficientRequires ordering/monotonicity
Dynamic programmingVariesHandles overlapping subproblemsCan consume memory
GreedyOften (O(n\log n))EfficientRequires proof of correctness
Graph algorithmsVariesSolves network problemsCan be conceptually complex

Python vs Lower-Level Languages

Python offers outstanding development speed, but C++ may outperform Python in some extremely time-sensitive contests.

FactorPythonC++
SyntaxVery conciseMore verbose
Development speedExcellentGood
Standard libraryPowerfulExtremely powerful
Raw execution speedLowerHigher
String processingExcellentExcellent
Rapid prototypingExcellentGood

For many algorithmic problems, choosing the correct algorithm matters far more than choosing the programming language.

Algorithm Map: A 128-Algorithm Learning Framework

The following classification provides a practical way to organize a large algorithmic toolkit.

ImageImage

 

Image

Image

CategoryRepresentative Techniques
SearchingLinear Search, Binary Search
SortingMerge Sort, Quick Sort, Counting Sort
ArraysPrefix Sum, Difference Array
StringsPattern Matching, Frequency Counting
Two PointersPair Search, Interval Processing
Sliding WindowMaximum/Minimum Window
HashingHash Maps, Hash Sets
StackMonotonic Stack
QueueBFS, Deque Optimization
HeapPriority Queue, Top-K
RecursionDivide and Conquer
BacktrackingPermutations, Combinations
GreedyInterval Scheduling
Dynamic ProgrammingKnapsack, LIS, Grid DP
GraphsBFS, DFS, Dijkstra
TreesTraversals, Binary Search Trees
MSTKruskal, Prim
Number TheoryGCD, Sieve, Modular Arithmetic
Bit ManipulationXOR, Bit Masks
Computational GeometryOrientation, Distance
OptimizationMemoization, State Compression

Examples

Example 1 — Binary Search

Suppose a sorted array contains:

[3, 8, 12, 17, 25, 31, 42]

Searching sequentially requires up to:

[O(n)]

Binary search repeatedly divides the search region approximately in half:

[O(\log n)]

Python provides a useful implementation through the bisect module.

from bisect import bisect_left

arr = [3, 8, 12, 17, 25, 31, 42]

position = bisect_left(arr, 25)

print(position)

The result is the insertion position of 25.

Example 2 — Frequency Counting

Hash-based counting is extremely useful for strings and arrays.

from collections import Counter

text = "engineering"

frequency = Counter(text)

print(frequency)

Instead of repeatedly scanning the string, the algorithm maintains a frequency table.

This technique appears in:

  • Anagram problems
  • Character counting
  • Duplicate detection
  • Frequency-based sorting
  • Data classification

Example 3 — Breadth-First Search

BFS explores a graph level by level.

from collections import deque

graph = {
    0: [1, 2],
    1: [3],
    2: [3],
    3: []
}

queue = deque([0])
visited = {0}

while queue:
    node = queue.popleft()

    for neighbor in graph[node]:
        if neighbor not in visited:
            visited.add(neighbor)
            queue.append(neighbor)

For an unweighted graph, BFS can determine the shortest number of edges between vertices.


Real-World Applications

Competitive programming algorithms are not restricted to contests.

Search Engines

Search systems depend on efficient indexing, searching, ranking, graph traversal, and optimization.

Network Engineering

Graph algorithms can model:

[\text{Routers} \rightarrow \text{Vertices}]

[\text{Connections} \rightarrow \text{Edges}]

Shortest-path algorithms can then help model routing decisions.

Engineering Optimization

Engineers frequently need to minimize:

[Cost = Material + Energy + Time]

Optimization algorithms provide mathematical frameworks for evaluating alternatives.

Software Engineering

Data structures and algorithms influence:

  • Database systems
  • Compilers
  • Operating systems
  • Distributed computing
  • Cloud services
  • Simulation software
  • Artificial intelligence

Technical Interviews

Many technology companies evaluate candidates using problems involving:

  • Arrays
  • Strings
  • Trees
  • Graphs
  • Dynamic programming
  • Complexity analysis

Therefore, competitive programming can become an effective training environment for technical interviews.


Common Mistakes

Writing Code Before Understanding the Problem

This often creates unnecessary complexity.

Solution: explain the algorithm in words before writing Python.

Ignoring Constraints

A correct algorithm can still fail if it is too slow.

For example:

[n=10^5]

An (O(n^2)) solution means approximately:

[10^{10}]

potential operations.

Overusing Recursion

Python recursion has practical limitations. Deep recursion may result in a recursion-depth error.

Using the Wrong Data Structure

Searching a Python list repeatedly can be much slower than using a set or dictionary for membership operations.

Forgetting Input Speed

For large inputs, this:

input()

may be less efficient than buffered input.

A common competitive programming pattern is:

import sys

input = sys.stdin.readline

Optimizing Without Measuring

Do not make code complicated merely because it looks faster.

First identify the real bottleneck.


Challenges & Solutions

ChallengeRecommended Solution
Problems seem too difficultBreak them into smaller patterns
Slow executionAnalyze complexity
Memory errorsReduce stored states
Incorrect answersTest edge cases
Poor algorithm selectionStudy problem patterns
Time pressurePractice timed contests
Python performanceUse efficient built-ins
Debugging difficultyBuild small test cases

Moving From Beginner to Advanced

A practical progression is:

[Arrays
\rightarrow
Searching
\rightarrow
Sorting
\rightarrow
Data\ Structures
\rightarrow
Graphs
\rightarrow
DP
\rightarrow
Advanced\ Algorithms]

Do not rush directly into advanced dynamic programming if fundamental array and graph techniques are still unfamiliar.


Case Study: Optimizing a Large Search Problem

Imagine an engineering application receives 500,000 measurements and needs to determine whether specific values exist in the dataset.

A beginner might repeatedly search a list:

for query in queries:
    if query in values:
        print("Found")

If the list is large and there are many queries, repeated linear searches can become expensive.

Improved Approach

Convert the values into a set:

values = set(values)

for query in queries:
    if query in values:
        print("Found")

The average membership operation becomes approximately:

[O(1)]

instead of:

[O(n)]

for each lookup.

The broader engineering lesson is important:

Algorithmic efficiency often comes from selecting the right representation of data.


Essential Tips

Think in Patterns

Do not memorize isolated solutions. Learn to recognize patterns.

If you see:

  • Sorted data → consider binary search.
  • Contiguous range → consider sliding window or prefix sums.
  • Shortest path → consider BFS/Dijkstra.
  • Repeated subproblems → consider dynamic programming.
  • Connectivity → consider DFS, BFS, or Union-Find.
  • Frequency queries → consider dictionaries or Counter.

Learn Complexity Analysis

Always ask:

[\text{How does runtime grow when }n\rightarrow\infty?]

This question separates algorithmic thinking from ordinary programming.

Master Python’s Standard Library

Knowing when to use set, dict, deque, heapq, bisect, and Counter can significantly simplify solutions.

Practice Consistently

A useful schedule might be:

Beginner: 2–3 problems/day
Intermediate: 3–5 problems/day
Advanced: timed contests + deep problem analysis

Review Failed Solutions

An incorrect submission is valuable if you determine why it failed.

Ask:

  1. Was the algorithm wrong?
  2. 💻 Was the complexity too high?
  3. 💻 Was there an edge case?
  4. Was integer handling incorrect?
  5. Was the implementation inefficient?

FAQs

What is competitive programming in Python?

Competitive programming is the practice of solving algorithmic problems under constraints such as execution time and memory. Python can be highly effective when combined with appropriate algorithms and efficient data structures.

Is Python good for competitive programming?

Yes. Python has concise syntax, powerful built-in data structures, and an extensive standard library. However, extremely performance-sensitive problems may favor C++.

What are the most important algorithms to learn first?

Start with searching, sorting, prefix sums, two pointers, sliding windows, stacks, queues, recursion, BFS, DFS, and basic dynamic programming.

Do I need to memorize 128 algorithms?

No. Understanding the principles is more important than memorization. You should be able to recognize a problem pattern and select an appropriate technique.

How long does it take to become good at competitive programming?

It depends on your previous programming experience and practice frequency. Consistent practice over several months can produce substantial improvement.

Is competitive programming useful for engineers?

Absolutely. It develops computational thinking, optimization skills, debugging ability, and familiarity with fundamental algorithms and data structures.

Should beginners start with dynamic programming?

Usually not. Beginners should first develop strong foundations in arrays, strings, searching, sorting, recursion, and basic data structures.

Can competitive programming help with coding interviews?

Yes. Many technical interviews involve algorithmic problems involving arrays, strings, graphs, trees, hash tables, and dynamic programming.


Conclusion

Competitive Programming in Python: 128 Algorithms to Develop Your Coding Skills represents more than a collection of algorithms. It represents a systematic approach to computational problem solving. 🚀

The most important lesson is not simply knowing that binary search runs in (O(\log n)), that hashing often provides (O(1)) average lookup, or that dynamic programming can eliminate repeated computation.

The deeper skill is knowing when to apply each technique.

From simple array manipulation to sophisticated graph algorithms and dynamic programming, these skills form a foundation that is valuable across software engineering, data science, artificial intelligence, systems engineering, and technical interviews.

For students, competitive programming develops mathematical and logical thinking. For professionals, it sharpens algorithmic decision-making. And for anyone learning Python, it provides a practical way to move from “I can write code” to “I can design efficient solutions.” 💻⚙️

The ultimate objective is therefore not to memorize 128 algorithms—it is to develop the engineering instinct to recognize a computational problem, model it correctly, select the right algorithm, analyze its complexity, and produce a reliable solution.

Unlock exclusive content
Enjoy all premium content by watching a short ad
Preparing ad...
BY ADX360