How to proof the time complexity of this Fibonacci sequence is O(n) - time-complexity

In the following code, i know that the time complexity is O(n) but how do i proof it in a proper way?
Is saying that searching array is O(n) enough?
int f[N];
F(n)
{
if (f[n] >= 0) return f[n];
f[n] = F(n-1) + F(n-2);
return f[n];
}
int main()
{
read n;
f[0] = 0; f[1] = 1;
for (i = 2; i <= n; i++)
f[i] = -1;
print F(n);
}

For each element of the array you call F. it may seem as a recursion to you but a bad implementation. each of the f[n-1] and f[n-2] calls actually just returns the values.
You will have 3n call to F(n), so still O(n).
If you are not obligated to recursion, you can program it with a single loop.

Related

Why the Big-O is O(n) and not O(n/2) of this code

I am trying to understand the Big-O of algorithms.
I found this code online and I wasn't able to understand how the Big-O was calculated for it:
void printFirstItemThenFirstHalfThenSayHi100Times(int arr[], int size)
{
printf("First element of array = %d\n",arr[0]); % O(1)
for (int i = 0; i < size/2; i++) % O(n/2)
{
printf("%d\n", arr[i]);
}
for (int i = 0; i < 100; i++) % O(100), which is a constant
{
printf("Hi\n");
}
}
It says (big-o-with-examples) that, the big-O is O(N)! why?
I see that we have a constant at the beginning O(1), then O(n/2), and finally O(100). Why the Big-O is O(N) and not O(N/2)?
Because Big-O(n) == Big-O(1/2 * n), drop the constant factor.
See Is there such a thing as O(n/2) in Big O notation?

Best time complexity of a single loop?

I have a really simple question, I have this loop:
for (int i=0; i<n; i++) {
"some O(n) stuff here)"
}
what will be the BEST time complexity of this algorithm?
O(n)? (for loop O(1) * O(n) stuff)
or
O(n^2)? (for loop O(n) * O(n) stuff inside the loop)
Will the for loop itself be considered as O(n) as normally, or will it be considered as O(1)
since it will only make only 1 loop for the BEST case scenario?
You are right, the best time complexity is O(N) (and even Θ(N)), if the best running time of "stuff" is constant (even zero).
Anyway, if "stuff" is known to be best case Ω(f(N)), then the best total time is Ω(N f(N)).
If your loop is doing O(n) stuff for n times then the time complexity will be O(n^2). May you call it worst case. The best case and average case will be based on your some O(n) stuff that is executed with every iteration of your loop.
Lets take a simple example of bubble sort algorithm:
for (int i = 0; i < n - 1; ++i) {
for (int j = 0; j < n - i - 1; ++j) {
if (a[j] > a[j + 1]) {
swap(&a[j], &a[j + 1]);
}
}
}
Time complexity this will always be O(n^2), whether array is sorted (irrespective of order - ascending or descending) or not.
But this can be optimised by observing that the nth pass finds the nth largest element and puts it into its final place. So, the inner loop can avoid looking at the last n − 1 items when running for the nth time:
for (int i = 0; i < n - 1; ++i) {
swapped = false;
for (int j = 0; j < n - i - 1; ++j) {
if (a[j] > a[j + 1]) {
swap(&a[j], &a[j + 1]);
swapped = true;
}
}
if (swapped == false) {
break;
}
}
Now the best case time complexity is O(n) i.e. when the array is sorted in ascending order (in context of above implementation). Average and worst case are still O(n^2).
So, to identify the best case time complexity of your algorithm you have to show us the implementation of some O(n) stuff and if not implementation then at least show the algorithm that you are trying to implement.
As you stated it, it's O(n^2).
'Cause You are doing n times a O(n) operation.

Time complexity of for loop with if/else

Would the following code be considered O(1) or O(n)? The for loop has constant complexity which runs 10 times but I'm not sure whether the if condition would be considered O(n) or O(1).
for (i = 0; i < 10; i++)
{
if (arr [i] == 1001)
{
return i;
}
}
The complexity would be O(1), because regardless of how much you increase the input the complexity of the algorithm remains constant. Namely, the operations performed inside that loop are considered to have constant time, hence O(1).
for (i = 0; i < 10; i++)
{
if (arr [i] == 1001)
{
return i;
}
}
On the other hand if your loop was:
for (i = 0; i < 10; i++)
{
f(n)
}
and the function f(n) had a complexity of O(n) then the complexity of the entire code snippet would be O(n) since 10 * N can be labeled as O(n).
For a more in depth explanation have a look at What is a plain English explanation of “Big O” notation?

Why is the time-complexity for modulus operation constant?

I am working through Cracking the Coding Interview, and I am unsure of an example on time-complexity. They provide this code to determine if a number is prime:
boolean isPrime(int n) {
for (int x = 2; x * x <= n; x++) {
if (n % x == 0) {
return false;
}
}
return true;
}
Later they say "The work inside the for loop is constant". Why is run-time for modulus operator constant? Why does it not depend on n?
The key part of the statement there is inside the for loop. All that's happening is a a modulo operation. Inside the function itself the time complexity depends on n

time complexity ( studying for exam)

I am currently studying to an examen in algorithms and I am trying to solve a question about time complexity in java, but can't really figure out how to do it. I am suppose to calculate the expected time complexity. N is a positive integer.
for (int i=0; i < N; i++)
for (int j=i+1; j < N; i++) {
int x=j+1; int h=N-1; int k;
while(x<h) {
k=(x+h)/2;
if (a[i]+a[j]+a[k] == 0) { cnt++; break;}
if (a[i]+a[j]+a[k] < 0) x=k+1;
else h=k-1;
}}
The first for loop should run N times and the second should run N-1. Since x is j+1 I guessed that x= N-2. I dont know how to think after that with the while loop or if I have done anything right. Would really appreciate help!
Create your time complexity function in parts.
for (int i=0; i < N; i++) //Takes linear O(n)
for (int j=i+1; j < N; i++) { //Takes linear O(n) and in computer science we can safely assume -1 is irrelevant at N-1 in big O notation
int x=j+1; int h=N-1; int k; // 3 x O(1)
while( x < h ) { // Worst case is when j equals i + 1 where i = 0 so x is at lowest 2 and h equals to N-1 so h depends on N. So again loop takes linear O(n) time.
k=(x+h)/2; // Takes O(1) time
if (a[i]+a[j]+a[k] == 0) { // Takes O(1) time and if this gives true we do break from the while loop
cnt++; // Takes O(1) time
break; // Takes O(1) time
}
if ( a[i]+a[j]+a[k] < 0 ) { // Takes O(1) time
x=k+1; // Takes O(1) time
} else {
h=k-1; // Takes O(1) time
}
}
}
}
So in summary T(N) equals to O(N^3) and Ω(N^2)
More specific T(N) = N * N-1 * N-2 + 10 and this last while loop in avarage takes O(N/2) time but still in computer science it is same as O(N).
We are only interested in worst and best cases.
To confuse even more big O notation actually
T(N)=O(g(N)) means this:
I hope this answer helps even little bit...