Excursion: Algorithm Analysis
Use big-O-notation for analyzing algorithms.
This lesson introduces the concept of big--notation for describing the worst-case runtime of an algorithm. If you are already familiar with big--notation, feel free to skip this lesson.
Counting operations
Computer science problems can be solved with various different algorithms. Naturally, this leads to the task of comparing different algorithms for the same problem to find out which one is the best. More often than not, this boils down to the question “which algorithm is the fastest?”
To measure and compare the runtime behavior of algorithms, we can count the number of operations that the algorithm must perform compared to the size of its input. For illustration, consider the following C++
-function that checks whether there are two elements in a vector
that sum to zero.
#include <iostream>#include <vector>using namespace std;bool twoSum(vector<int> numbers) {for (int a : numbers) {for (int b : numbers) {int sum = a + b;if (sum == 0) {return true;}}}return false;}int main() {vector<int> example {-2, 3, 2, 6};cout << (twoSum(example) ? "true" : "false");}
Let’s say that we pass a vector
with elements to twoSum
. How many operations will it perform?
Actually, this will depend on the contents of the vector. If the first two elements are already summed to zero, the function will finish much quicker than if the last two elements sum to zero. Therefore, we usually focus on the worst-case runtime of an algorithm. In the case of twoSum
, the worst case happens when there are no two numbers of the vector
that sum to zero. In that case, both loops run over all elements and finally return false
.
So, let’s count the operations that twoSum
performs in the worst case on an input vector
of size . There are two nested for
-loops looping over elements, so the code inside these loops is executed times. There are two statements happening there: the addition and the if
-condition. This makes ...