Skip to content
23 changes: 23 additions & 0 deletions Amortized1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Solution Approach

Note that the variable j is not initialized for each value of variable i.
Hence, the inner j++ will be executed at most n times.
The i loop also runs n times.
So, the whole thing runs for O(n) times.


**Still not convinced ?**

Lets assume the array passed has its element in decreasing order. We will just dry run through the code :

Iteration 1 : i = 0, j = 0. arr[0] < arr[0] is false. So, the inner while loop breaks.
Iteration 2: i =1, j = 0. arr[1] < arr[0] is true. j becomes 1.
Iteration 3 : i = 1, j = 1. Condition false. We break. Note that j will remain 1 and is not reset back to 0.
Iteration 4 : i = 2, j = 1. arr[2] < arr[1]. True. j = 2.
Iteration 5 : i = 2, j = 2. Condition false. Break.
Iteration 6 : i = 3, j = 2. arr[3] < arr[2]. True. j = 3.
Iteration 7 : i = 3, j = 3. Condition false. Break.


As you can see, the inner while loop only runs once in this case.
So, total iterations is **2 * N.**
30 changes: 30 additions & 0 deletions Choose1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Solution Approach

The order of growth of option (C) is n^2.5 which is higher than n^2.

Lets look at it with a different approach :

f(n) = O(n^2) if
f(n) <= C * n^2 for n > n0.


Lets look at every option one by one.

* Option 1 :

(15^10) * n + 12099
Lets say C = 16^10
15^10 * n + 12099 < 16^10 * n^2 for n > 1.
So, it is O(n^2).


* Option 2 : n^1.98

C = 1.
n^1.98 < n^2 for n > 1.
So, its O(n^2) ```
Option 3 : n^3 / (sqrt(n)) or n^2.5
There is no possible combination of C and n0 possible
Option 4 : 2^20 * n
C = 2^20, n0 = 1
2^20 * n <= 2^20 * n^2 for n > 1
3 changes: 3 additions & 0 deletions Choose2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Solution Approach

Try to look at the values for functions for very large value of n.
9 changes: 9 additions & 0 deletions Choose3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Solution Approach

The time complexity of the first for loop is O(n).

The time complexity of the second for loop is O(n/2), equivalent to O(n) in asymptotic analysis.

The time complexity of the third for loop is O(logn).

The fourth for loop doesn't terminate.
4 changes: 4 additions & 0 deletions Choose4/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Solution Approach

In asymptotic analysis we consider growth of algorithm in terms of input size.
An algorithm X is said to be asymptotically better than Y if X takes smaller time than y for all input sizes n larger than a value n0 where n0 > 0.
23 changes: 23 additions & 0 deletions GcdCmpl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Solution Approach

Let us say n = fibonacci(N) and m = fibonacci(N - 1)

fibonacci(N) = fibonacci(N-1) + fibonacci(N-2)

OR n = m + k where k < m.

Therefore the step

n = n % m will make n = k

swap(n, m) will result in

n = fibonacci(N-1)

m = k = fibonacci(N-2)

So, it will take N steps before m becomes 0.

This means, in the worst case, this algorithm can take N step if **n** is Nth fibonacci number.

**Think of whats the relation between N and n**.
7 changes: 7 additions & 0 deletions LOOP_CMPL/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# solution approach

The first loop is O(N) and the second loop is O(M).

Since you don't know which is bigger, you say **this is O(N + M)**. This can also be written as O(max(N, M)).

Since there is no additional space being utilised, the space complexity is constant / O(1)
34 changes: 34 additions & 0 deletions LoopCmpl2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Solution Approach

Lets look at the code we are evaluating :

int i, j, k = 0;
for (i = n/2; i <= n; i++) {
for (j = 2; j <= n; j = j * 2) {
k = k + n/2;
}
}


Now, lets just assume `n = 8` for now.
We will try to see, the values of j corresponding to each i.

i = 4, j = 2, 4, 8
i = 5, j = 2, 4, 8
i = 6, j = 2, 4, 8
i = 7, j = 2, 4, 8
i = 8, j = 2, 4, 8


If you notice, j keeps doubling till it is less than or equal to n. Number of times, you can double a number till it is less than n would be log(n).

Lets take more examples here to convince ourselves.

n = 16, j = 2, 4, 8, 16
n = 32, j = 2, 4, 8, 16, 32


So, j would run for O(log n) steps.
i runs for n/2 steps.

So, total steps ` = O (n/ 2 * log (n)) = O(n logn) `
5 changes: 5 additions & 0 deletions NestedCmpl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Solution Approach

The first set of nested loops is O(N^2) and the second loop is O(N).

This is O(max(N^2,N)) which is O(N^2).
9 changes: 9 additions & 0 deletions NestedCmpl2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Solution Approach

Total number of runs = N + (N - 1) + (N - 2) + ... 1 + 0

= N * (N + 1) / 2

= 1/2 * N^2 + 1/2 * N

O(N^2) times.
11 changes: 11 additions & 0 deletions NestedCmpl3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Solution Approach

In the first iteration, the j loop runs N times.

In the second iteration, the j loop runs N / 2 times.

In the ith iteration, the j loop runs N / 2^i times.

So, the total number of runs of loop = N + N / 2 + N / 4 + ... 1

= **N * ( 1 + 1/2 + 1/4 + 1/8 + ... ) < 2 * N**
18 changes: 18 additions & 0 deletions RecCmpl1/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Solution Approach

It might seem at the first look that the program is O(log N).
However, the last case

return searchNumOccurrence(V, k, start, mid - 1) + 1 + searchNumOccurrence(V, k, mid + 1, end);


is the bottleneck step.
Assuming all the values in the array are the same, we get the following relation :

T(N) = 2 * T(N/2) + constant
= 4 * T(N/4) + constant ( 2 * constant = another constant )
= 8 * T(N/8) + constant
= N * T(N/N) + constant
= N + constant
= O(N)
21 changes: 21 additions & 0 deletions RecCmpl2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Solution Approach

Note that in every function call, we end up making 2 calls.

So, the function calls ends up looking like a tree :

F(0,0)
/ \
F(0, 1) F(1, 0)
/ \ / \
F(0, 2) F(1,1) F(1, 1) F(2, 0)
....
The function calls end up making a complete binary tree.

Number of calls on Level 0 = 1
Number of calls on Level 1 = 2
Number of calls on Level 2 = 4
...
Number of calls on level i = 2^i.
Total number of calls = 1 + 2 + 4 + ... 2^i + ... 2^(M + N - 2)
= O(2^(M + N))
19 changes: 19 additions & 0 deletions RecCmpl3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Solution Approach

Note that for a given `(r, c)`

the following code will not be executed more than once :

memo[r][c] = V[r][c] + min(findMinPath(V, r + 1, c), findMinPath(V, r, c + 1));


Once memo[r][c] is set, the functions will return at

if (memo[r][c] != -1) return memo[r][c];


So, every function ends up calling other functions at most 1 time.
In other words, every function ends up executing atmost O(1) times (Note that you can shift the part about checking for memo[r][c] != -1 at the callsite ).

`O(R * C)` possible number of combinations are possible for `(r, c)`
Hence, the time complexity of the function : O(R*C)
5 changes: 5 additions & 0 deletions WhileCmpl/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Solution Approach

We have to find the smallest x such that `N / 2^x < 1 OR 2^x > N`

x = log(N)