How to find the time complexity of nested for-loop - language-agnostic

What is the time complexity for the nested loops shown below:
1)
for (int i = 1; i <=n; i += 2) {
for (int j = 1; j <=n; j += 2) {
// some O(1) expressions
}
}
2)
for (int i = 1; i <=n; i += 3) {
for (int j = 1; j <=n; j += 3) {
// some O(1) expressions
}
}
In general:
for (int i = 1; i <=n; i += c) {
for (int j = 1; j <=n; j += c) {
// some O(1) expressions
}
}
Is is really this the following? O(nc)

Your algorithm will execute (n / c) * (n /c) iterations. We're dividing, because we are skipping c characters for each iteration. See that:
for (var i = 0; i <= n; i = i + 1)
Will have n / 1 iterations
for (var i = 0; i <= n; i = i + 2)
Will have n / 2 iterations
*Note that the result will be floored. That is, if n = 3 and c = 2, it will execute only one time (floor(3 / 2) == 1)
So, we can generalize it to be
(n / c)2
= (n2/c2)
= 1/c2 * n2
Remember that Big O is only interested in the rate of change. Since c is a constant, it is ignored from the calculation.
So, the result is:
O(1/c2 * n2) = O(n2)

For the general case, the inner loop has O(n) and the outer loop has O(n). Therefore, for each iteration of the outside loop, the inner loop iterates n times (c does not matter for order of complexity and should be treated as if it is 1). If the outer loop iterates n times, the total number of iterations in the inner loop is n*n, or O(n^2).

Imagine there are 10 chairs (n here)
in one for loop you are iterating over all the chairs, let say you sit on all the chairs, so in total you need to sit 10 times to sit on all the chairs for a given loop.
Now imagine you sit on first chair and ask your friend to sit on the other chairs one by one including your chair, so in total your friend has to sit on 10 chairs.
Now you choses the second chair, and again ask you friend to sit on each chair again, so in total he again has to sit on 10 chairs.
Similarly you can choose the 3rd,4th... chair and so on, so in total your friend has to sit on 10 chairs for each of the chair you choose.
10 + 10 + ... = 100 times
which is equivalent to 10^2 = 100
So the complexity is O(n^2), where n is the number of chairs.

Related

Order of growth for g(x)

int f (int x)
{
if (x < 1) return 1;
else return (f(x-1) + g(x));
}
int g (int x)
{
if (x < 2) return 2;
else return (f(x-1) + g(x/2));
}
How to calculate the order of growth for g(x) here?
For calculating order of f and g we need to calculate both and the worst order is the answer because they are adding to each other in both function. for example between n and n/2 , n is the worst so the order is n.
Whenever f is called it's f(x-1) , then the order is n. and in g function we have g(x/2) that it means the order of g(x/2) is n/2 because x divided by 2 every time.
So in g we have order n + n/2 and the worst order is n so the result of "order of g(x)" is n.

Writing Fibonacci Sequence Elegantly Python

I am trying to improve my programming skills by writing functions in multiple ways, this teaches me new ways of writing code but also understanding other people's style of writing code. Below is a function that calculates the sum of all even numbers in a fibonacci sequence up to the max value. Do you have any recommendations on writing this algorithm differently, maybe more compactly or more pythonic?
def calcFibonacciSumOfEvenOnly():
MAX_VALUE = 4000000
sumOfEven = 0
prev = 1
curr = 2
while curr <= MAX_VALUE:
if curr % 2 == 0:
sumOfEven += curr
temp = curr
curr += prev
prev = temp
return sumOfEven
I do not want to write this function recursively since I know it takes up a lot of memory even though it is quite simple to write.
You can use a generator to produce even numbers of a fibonacci sequence up to the given max value, and then obtain the sum of the generated numbers:
def even_fibs_up_to(m):
a, b = 0, 1
while a <= m:
if a % 2 == 0:
yield a
a, b = b, a + b
So that:
print(sum(even_fibs_up_to(50)))
would output: 44 (0 + 2 + 8 + 34 = 44)

What's the time complexity of the following code?

What's the time complexity of the following code?
a = 2;
while (a <= n)
{
for (k=1; k <= n; k++)
{
b = n;
while (b > 1)
b = b / 2;
}
a = a * a * a;
}
I'm struggling with the outer while loop, which is loglogn, I can't understand why. How would the time complexity change if the last line was a = a * a * a * a;?
the for loop is O(n), and inner one is O(logn).
So in total, O(n*logn*loglogn)
a values would be:
a = 2 2^3 2^9 2^27 2^81 ...
and so on.
Now let's assume that the last value of a is 2^(3^k)
Where k is the number of iterations of the outer while loop.
For simplicity let's assume that a = n^3, so 2^(3^k) = n^3
So 3^k = 3*log_2(n) => k = log_3(3log_2(n)) = š›©(loglogn)
If the last line was a = a * a * a * a the time-complexity would remain š›©(loglogn) because k = log_4(4log_2(n)) = š›©(loglogn).
the loop is running n times and the inner loop has time complexity is log n so total time complexity is O(n log n)

What is the time complexity of the following pseudocode?

XYZ(a, b, c, m, n){
For p = 1 to m do
For q=p to n do
c[p,q] = a[p,q] + b[p,q];}
I think it is n + n-1 + n-2 +.....+(n-m+1). But I am not sure. Is it this or m*n?
Let's simplify your code :
For p from 1 to m
For q from p to n
Do something
Assuming the Do something part is done in constant time, what determines the time complexity of the code are the two loops. The outer loop runs m times, while the inner loop runs n-p, with p going from 1 to m.
If m >= n, the Do something part is repeated n+(n-1)+...+1 = n*(n+1)/2 = nĀ²/2 + n/2 = O(nĀ²) times.
Otherwise, if n > m, it's repeated n+(n-1)+...+(n-m+1) = (n*(n+1) - (n-m)*(n-m+1))/2 = 1/2 * (nĀ² + n - nĀ² + 2*n*m - n - mĀ² + m) = O(2*n*m - mĀ²) = O(nĀ²) times.
In any case, O(nĀ²) is a right answer, but if n >> m, a more precise answer is O(n*m).

What does the following code does?

I was given in university the following code to explain shortly what it does and what is the value of x at the end of the run as a function of n, hope someone could help me.
x = 0;
for(int i = n; i > 1; i--) {
for(int j = 1; j < i; j--) {
x +=5;
}
}
Thanks
(I assume you meant to write "j++" instead of "j--", and not end up in an infinite loop?)
If so, just execute it by hand.
The outer loop iterates with i over the integers, from n down to 2 (inclusive).
At each iteration of that loop, the inner loop iterates with j over the integers from 1 up to i - 1 (inclusive).
thus, x is incremented by 5 for each of:
j = 1, 2, ... n - 1
then, each of:
j = 1, 2, ... n - 2
then, etc,
...
until,
j = 1
if I'm not mistaken, that's n * (n - 1) / 2 iterations in total
(cf. the arithmetic progression)
to give eventually,
x == 5 * n * (n - 1) / 2
E.g., for n = 3:
x == 15
'HTH
for(int i = n; i > 1; i--) {
for(int j = 1; j < i; j--) {
since i > 1 and j=1; j < i; j--.
j will always be less than i so it becomes an infinite loop.