diff --git a/Amortized1/README.md b/Amortized1/README.md new file mode 100644 index 0000000..3ddc499 --- /dev/null +++ b/Amortized1/README.md @@ -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.** diff --git a/Choose1/README.md b/Choose1/README.md new file mode 100644 index 0000000..0938475 --- /dev/null +++ b/Choose1/README.md @@ -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 diff --git a/Choose2/README.md b/Choose2/README.md new file mode 100644 index 0000000..e9522a3 --- /dev/null +++ b/Choose2/README.md @@ -0,0 +1,3 @@ +# Solution Approach + +Try to look at the values for functions for very large value of n. diff --git a/Choose3/README.md b/Choose3/README.md new file mode 100644 index 0000000..6727522 --- /dev/null +++ b/Choose3/README.md @@ -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. diff --git a/Choose4/README.md b/Choose4/README.md new file mode 100644 index 0000000..da771b8 --- /dev/null +++ b/Choose4/README.md @@ -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. diff --git a/GcdCmpl/README.md b/GcdCmpl/README.md new file mode 100644 index 0000000..fa97ef0 --- /dev/null +++ b/GcdCmpl/README.md @@ -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**. diff --git a/LOOP_CMPL/README.md b/LOOP_CMPL/README.md new file mode 100644 index 0000000..917c4ea --- /dev/null +++ b/LOOP_CMPL/README.md @@ -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) diff --git a/LoopCmpl2/README.md b/LoopCmpl2/README.md new file mode 100644 index 0000000..6fc36f7 --- /dev/null +++ b/LoopCmpl2/README.md @@ -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) ` diff --git a/NestedCmpl/README.md b/NestedCmpl/README.md new file mode 100644 index 0000000..0567a03 --- /dev/null +++ b/NestedCmpl/README.md @@ -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). diff --git a/NestedCmpl2/README.md b/NestedCmpl2/README.md new file mode 100644 index 0000000..f444678 --- /dev/null +++ b/NestedCmpl2/README.md @@ -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. diff --git a/NestedCmpl3/README.md b/NestedCmpl3/README.md new file mode 100644 index 0000000..f62103e --- /dev/null +++ b/NestedCmpl3/README.md @@ -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** diff --git a/RecCmpl1/README.md b/RecCmpl1/README.md new file mode 100644 index 0000000..cb47854 --- /dev/null +++ b/RecCmpl1/README.md @@ -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) diff --git a/RecCmpl2/README.md b/RecCmpl2/README.md new file mode 100644 index 0000000..c056971 --- /dev/null +++ b/RecCmpl2/README.md @@ -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)) diff --git a/RecCmpl3/README.md b/RecCmpl3/README.md new file mode 100644 index 0000000..09b9683 --- /dev/null +++ b/RecCmpl3/README.md @@ -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) diff --git a/WhileCmpl/README.md b/WhileCmpl/README.md new file mode 100644 index 0000000..e630596 --- /dev/null +++ b/WhileCmpl/README.md @@ -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)