Time Complexity Calculation Template
- O(n)
1 | for i := 0; i < n; i++ { |
- O(n2)
1 | for i := 0; i < n; i++ { |
- O(n2)
1 | for i := 0; i < n; i++ { |
Explaination:
i | j |
---|---|
0 | 0 |
1 | 1 |
2 | 2 |
… | … |
n | n |
So the complexity is : 1 + 2 + 3 + ... + n = n * (n + 1) / 2
= O(n2)
- O(
)
1 | for i, j := 0, 0; j < n; i++ { |
Explaination:
i | j |
---|---|
0 | 0 |
1 | 0 + 1 |
2 | 0 + 1 + 2 |
3 | 0 + 1 + 2 + 3 |
… | … |
k | 0 + 1 + 2 + 3 + … + k |
We need to find the solution for 1 + 2 + 3 + ... + k > n
=> k
>
- O(
)
1 | for i := 1; i <= n; i *= 2 { |
Explaination:
We need to find the solution for 2<sup>k</sup>
< n
=> k
<
- O(
)
1 | for i := n; i >= 1; i /= 2 { |
Explaination:
We need to find the solution for k
<
- O(
)
1 | for i := 0; i * i < n; i++ { |
Explaination:
We need to find the solution for k2 < n => k
<
- Time complexity for resursion.
a. T(n) = T(n - 1) + 1 => O(n)
1 | func x(n int) { |
b. T(n) = T(n - 1) + n => O(n2)
1 | func x(n int) { |
Explaination:
T(n) = T(n - 1) + n = T(n - 2) + (n - 1) + n = T(n - 3) + (n - 2) + (n - 1) + n = … = T(1) + 1 + 2 + 3 + … + n
c. T(n) = T(n - 1) +
1 | func x(n int) { |
Explaination:
Similar like 8.b, the time complexity will be
d. T(n) = 2 * T(n - 1) + 1 => O(2n)
1 | func x(n int) { |
Explaination:
Similar like 8.b, the time complexity will be T(n) = 2 * T(n - 1) + 1 = 4 * T(n - 2) + 2 + 1 = 8 * T(n - 3) + 4 + 2 + 1 = … = 2n * T(0) + 2n-1 + 2n-2 + … + 4 + 2 + 1 = 2n + 1 - 1 [Geometric Sequence]
e. T(n) = T(n / 2) + 1 => O(
1 | func x(n int) { |
Explaination:
Similar like 8.b, the time complexity will be T(n) = T(n - 1) + 1 = T(n - 2) + 1 + 1 = … = T(
f. T(n) = T(n / 2) + n => O(n)
1 | func x(n int) { |
Explaination:
Similar like 8.3, the time complexity will be T(n) = T(n/2) + n = T(n/4) + n / 2 + n = … = T(n/2k) + n / 2k-1 + … + n / 21 + n / 20 = T(1) + n * (1 / 2k-1 + … + 1 / 21 + 1 / 20) = O(n) [Geometric Sequence]
g. T(n) = 2T(n / 2) + n => O(n
1 | func x(n int) { |
Explaination:
Similar like 8.3, the time complexity will be T(n) = 2 * T(n/2) + n = 4 * T(n/4) + n + n = 8 * T(n / 8) + n + n + n = … = 2k * T(n / 2k) + k * n = n * T(1) +
Now, Let’s take a look at a problem from Leetcode 50. Pow(x, n).
a. Brute-force solution O(n) => template #8.a
1 | func myPow(x float64, n int) float64 { |
Golang Playbook: https://play.golang.org/p/YxdrpGt-VXT
b. Let’s try recursive solution I O(n)
1 | func recursivePow(x float64, n int) float64 { |
Golang Playbook: https://play.golang.org/p/O_MPA_gORmA
NOTE: This is still O(n) since the recursivePow
was invoked n
times
c. Let’s try recursive solution II
1 |
|
Golang Playbook: https://play.golang.org/p/m2azp6-WuLF
NOTE: Actually, this idea comes as a Divide & Concor solution, but if you count how many times recursivePow
are invoked, you will find that it’s still O(n). You can consider the input as a BST’s root node, so our target is to get the nodes number. It will be n.
d. Optimized cached recursive solution III O(
1 |
|
Golang Playbook: https://play.golang.org/p/lzC2k6QgLlF
The only difference between c
and d
is we cached the result of the function call recursivePow
. This will be similar like the binary search, each time we save half of the computation time.
[Refs]