Algorithm complexity in 5 minutes
What is algorithm complexity, and why is it important to calculate it?
The complexity of an algorithm is a measure of how much more difficult the computational process becomes as the input data increases.
Example:
To iterate through a list of 10 elements, you need to perform 10 iterations. If the list were 1,000 elements long, you’d have to perform 100 times more steps.
And if, in addition, every third element needs to be placed in a new separate list, then you will have to additionally use another 300+ memory cells.
Why calculate the complexity of an algorithm?
If an algorithm requires significant computing power and the volume of input data is large, then the code needs to be optimized as much as possible to speed up the calculations.
What is Big O?
Let’s start with the fact that no one needs to know the exact complexity of an algorithm. Estimation is performed asymptotically, i.e., by answering the question:
If we increase the size of the input data indefinitely, how will the performance of our algorithm change?
This asymptotic estimate is usually performed using Big O or O-notation. It indicates the function that bounds the asymptotic complexity of our algorithm. In other words, if the algorithm’s complexity is O(g), then as the input data size increases, the algorithm’s complexity grows no faster (or even slightly slower) than the function g.
Example:
The complexity of iterating over a collection is O(n). This means that the algorithm’s complexity will grow linearly. Increase the data volume by 10 times, and the complexity will increase by 10 times. Increase it by 100 times, and the complexity will increase by 100 times.
Note: Other notations are also used: omega, small O, etc. But big O is the main and most common instrument.
Basic rules of calculation
- If the operation does not depend on the amount of data, then it has constant complexity O(1)Examples:
- Extract the first element of a collection
- Add two numbers
- Adding up the complexity classes leads to the choice of greater complexity
- If you need to add 2 numbers and then multiply the result by 5, then the complexity of such an operation is O(max(1, 1)) = O(1)
- If you need to loop through a list (complexity O(N)) and at the end select only the first element (complexity O(1)), then the final complexity will be O(max(N, 1)) = O(N)
- If the operation does not depend on the amount of data, then it has constant complexity O(1)Examples:
Note: In reality, it’s not just the maximum complexity that’s chosen, but rather their summation. For example, O(N + 1). But as the input data approaches infinity, the larger function (N) will overwhelm the smaller one (1). Therefore, only the maximum is chosen.
- The complexity of IF blocks is calculated using the formula: O(complexity of the condition) + max(O(code in if), O(code in else)).
Example: if the number is greater than N, square it, otherwise iterate over the list arr of length N.
The complexity of the condition “if a number is greater than N” is O(1), which is a simple comparison. The complexity of “square it” is O(1). The complexity of “iterate over a list arr of length N” is O(N).
Total complexity: O(1) + max(O(1), O(N)) = O(1) + O(N) = O(N) .
- When multiplying, the difficulty classes are multiplied
Example:
– If we loop through the collection and multiply each element by 5, then the complexity will be O(N*1), since the complexity of multiplication is O(1) and we repeat this operation N times.
– If we loop through the collection and multiply each element by all the others (that is, for each element we loop through the remaining elements again), then the complexity will be O(N*1)*O(N*1) = O(N*N) = O(N^2) .
Main types of complexity
- Constant O(1)
- extracting the first element
- arithmetic operations between numbers
- Linear O(N)
- standard for loop
- Logarithmic complexity O(log N) – only half of the elements are taken at each iteration
- Divide and Conquer algorithms, such as binary search
- Linear arithmetic or linearized O(n * log n)
- Logarithmic complexity O(log N) – only half of the elements are taken at each iteration
- merge sort
- Quadratic – O(n^2)
- double cycle
- bubble sort
Best, worst, and average difficulty
It’s not always possible to fully estimate the complexity of an algorithm. It depends heavily on the input data: in one case, an algorithm may exhibit linear complexity, while in another, it may exhibit quadratic complexity.
Example: at best, bubble sort has O(N) complexity (when the array is already sorted), at worst – quadratic O(N^2).
Therefore, it’s customary to evaluate at least the best and worst case scenarios. But it’s better to focus on the worst-case scenario.
The “average” case is also often used as the main characteristic. This is the algorithm’s complexity based on average data. This approach is convenient because the probability of accurately hitting the “best” or “worst” case is low in practice.
Example: You need to find a given element in a list of N elements. In the best case, this element will be the first one, in which case the complexity will be O(1). In the worst case, the desired element will be the last one, in which case the complexity will be O(N). However, on average, you’ll have to make N/2 comparisons, meaning the average complexity is O(N/2) = O(N).
Calculation example
Let’s calculate the complexity of the following code. The FindDuplicates function checks whether the array arr contains duplicates. If so, it returns True; otherwise, it returns False.
def FindDuplicates(arr):
for ind, elem in enumerate(arr):
if elem in arr[ind+1:]:
return True
return False- Cycle complexity is O(N)
- The complexity of creating a slice arr[ind+1:] is O(N)
- The complexity of checking in is O(N)
- The complexity of the return operation is O(1)
Total complexity: O(N)*[O(N) + O(N) + O(1)] = O(N^2)
It turns out that if the input data increases by 2 times, it will be necessary to perform 4 times more operations.
Conclusion: Writing Smarter, Not Just Faster
In just five minutes, you’ve mastered the core blueprint of algorithmic efficiency. Algorithm complexity and Big O notation aren’t just academic concepts; they are the ultimate tools for predicting how your code will behave in the real world before it ever hits production.
The Key Takeaways:
Think Asymptotically: Always focus on the worst-case scenario ($O(N)$, $O(N^2)$, etc.) because that is where your code will struggle as data grows toward infinity.
Drop the Constants: Don’t get bogged down in exact step counts. Look for the dominant loops, nested structures, and slicing operations that truly drive performance.
Proactively Optimize: Spotting an $O(N^2)$ bottleneck early—like our duplicate finder example—allows you to rewrite the logic (perhaps using a Hash Set to drop it to $O(N)$) before a surge in user data crashes your application.
Hardware will always get faster, but hardware cannot fix an inherently inefficient algorithm. By keeping Big O in mind every time you write a loop or design a function, you ensure your code remains elegant, scalable, and lightning-fast—no matter how massive the data gets.
Explore More IT Terms
#
A
- A Guide to SQL Query Formatting
- A/B testing
- Agile
- Algorithm complexity in 5 minutes
- Algorithms and Data Structures in C#
- An overview of the C # programming language
- An overview of the Python programming language
- Anaconda Python
- Android
- Android App Bundle
- Android SDK
- Angular
- Ansible
- Apache
- Apache Airflow
- Apache Kafka
- Apache Tomcat
- App Store
- AppCode
- Array-based stack
- ArrayList
- ASCII
- ASP.NET
- Assembly Language Lessons
B
C
D
- Data Analytics: applications of data analysis in companies
- Data Engineer - Who is it, what does a data engineer do, and an overview of the profession
- Data modeling: what it is, types, and process steps.
- Data preprocessing: a complete guide for beginners and professionals.
- Data structure
- Data structures
- Defining Aliases
- Defining Arrays
- Deque
- Developing a Website from Scratch
- Digital data: understand the importance of this asset for businesses.
- Doubly linked lists
E
F
H
- Handling errors and exceptions
- How to effectively organize your workflow
- How to Learn Java: Tips for Beginner Developers
- How to Learn PHP: A Beginner's Guide
- How to Use S3 Storage in Kubernetes with CSI
- HTML
- HTML and CSS: Definition, Application, and Operating Principles
- HTML and CSS. Layout from Scratch: What to Learn, Where to Learn, and How Long Will It Take?
- HTML Frame Structure
- HTML Link Formatting
I
- if..else construction
- Inserting an Image
- Interactive Python Tutorial – Learn Programming from Scratch
- Interview Problem: Finding a Deleted Element in O(N)
- Interview Scare: The FizzBuzz Challenge
- Introduction to C++
- Introduction to Machine Learning
- Introduction to programming languages
- IT Specialist Resume (CV)
K
M
O
P
S
- SFML Graphics Library Tutorials
- SQL commands: see what they are, what the main ones are + examples
- SQL Interview Questions and Tasks
- SQL Lessons
- SQL Stored Procedures
- SQL Syntactic Sugar: The COALESCE Function
- Stack
- Start in analytics: Python or R
- Statistical analysis: importance for decision making.
- String formatting in Python
- Swift Lessons
- switch/match construct
T
W
- What are databases, and why do they need DBMS and SQL?
- What do Linux distributions consist of?
- What is .NET and what is it used for?
- What is a GPU in a computer, in simple terms?
- What is Big Data? Introduction, Types, Characteristics, and Examples
- What is Golang and what is it used for?
- What is Haskell and what is it used for?
- What is Kotlin and what is it used for?
- What is Linux? The History of Linux
- What is machine learning, and how does it work?
- What is Power BI: everything about the data analytics software
- What is the C++ programming language?
- What is the OSI Model: A Complete Explanation of the Seven Layers and Their Role in Networking
- Where to start learning the C programming language?
- Which Linux distribution should you choose? A Linux distribution overview
