Time Complexity
Edit: Assuming "ideal" conditions, no UB, no pre-sorted elements,...
Yes, you are partially correct. Adding a single element into an std::set
is indeed `O(log(N)).
Why?
std::set
is implemented as a balanced binary search tree (BBST), therefore if the element is smaller than the value you would go into the left subtree and vice-versa, hence inserting an element takes O(log(N))
because you are "splitting" the tree in half every iteration.
Let's break it down:
First Block:
vector<int> v(n);
for(int i = 0 ; i < n ; i++)
{
v[i] = i;
}
Here you initialize an std::vector
of size n
and use a for-loop
to initialize the elements. We know that your for-loop
runs n-times
and using the []
operator does not cost you anything (O(1)
), hence the time complexity of the first block is O(n)
.
Side Note: use .at()
instead of the []
operator since it gives you "auto" bounds checking.
Second Block:
set<int> s;
for(int i = 0 ; i < n ; i++)
{
s.insert(v[i]);
}
Here you initialize an std::set
of integers and you use a for-loop
, which takes O(n)
to insert the elements that are in the std::vector
into your std::set
. Using .insert()
takes O(log(N)) time, since in order to find the appropriate spot to insert the element it performs Binary Search
under the hood. Hence your second block takes O(Nlog(N))
time.
Now if you add that together (proof) eg:
T(n) = C*f(N)
=< N + Nlog(N) (for all n =< 1)
=< Nlog(N) + Nlog(N) //raise all to the highest power
=< 2Nlog(N)
since T(n) = C*f(n)
C = 2
f(n) = Nlog(N) //--> your big O
The overall time complexity is O(Nlog(N))
. I hope this is enough detail for you.