π£ 1. Big-O Notation
πΒ 1. big-O
1. An Analogy
- λμ€ν¬μ μλ νμΌμ λ€λ₯Έ μ§μμ μ΄κ³ μλ μΉκ΅¬μκ² κ°λ₯ν 빨리 보λ΄λ €κ³ νλ€κ³ κ°μ ν΄λ³΄μ.
λλΆλΆμ μ¬λλ€μ λ¬Έμ λ₯Ό λ£μλ§μ μ¨λΌμΈ μ λ°©μμ μκ°νκ³€ νλ€.
But, κ²½μ°μ λ°λΌ λ§μ μλ ν릴 μλ μλ€.
- νμΌμ ν¬κΈ°κ° μλ€λ©΄ λΉμ°ν μ¨λΌμΈμ ν΅ν μ μ‘μ΄ λΉ λ₯Ό κ²μ΄λ€.
- κ·Έλ¬λ νμΌμ ν¬κΈ°κ° μμ£Ό ν¬λ€λ©΄ λΉνκΈ°λ₯Ό ν΅ν΄ 물리μ μΌλ‘ λ°°λ¬νλ κ² λ λΉ λ₯Ό μλ μλ€.
- μ€μ λ‘ 1TB ν¬κΈ°μ νμΌμ μ¨λΌμΈμ ν΅ν΄ μ μ‘νλ € νλ€λ©΄ ν루 μ΄μ 걸릴 μλ μλ€.
2. Time Complexity
- μ κ·Όμ μ€ν μκ°(asymptoticc runtime)
- big-O
- μ¨λΌμΈ μ μ‘ $O(s)$
- μ¬κΈ°μ sλ νμΌμ ν¬κΈ°κ° λλ€.
- νμΌμ ν¬κΈ°κ° μ¦κ°ν¨μ λ°λΌ μ μ‘ μκ° λν μ νμ μΌλ‘ μ¦κ°νλ€.
- λΉνκΈ°λ₯Ό ν΅ν μ μ‘
- νμΌ ν¬κΈ°μ κ΄κ³μμ΄ $O(1)$
- νμΌμ ν¬κΈ°κ° μ¦κ°νλ€κ³ ν΄μ μΉκ΅¬μκ² νμΌμ μ μ‘νλ λ° κ±Έλ¦¬λ μκ°μ΄ λμ΄λμ§ μλλ€.
- β΄ μμ μκ° λ§νΌ μμλλ€.
- μμκ° μΌλ§λ ν°μ§ or μ νμμ΄ μΌλ§λ μ²μ²ν μ¦κ°νλμ§μ κ΄κ³μμ΄ μ«μκ° μ»€μ§λ€ 보면 μ νμμ μΈμ κ° μμλ₯Ό λ°μ΄λκ² λλ€.
- κ·Έ λ°μ λ€μν μ€ν μκ°
- O(log N)
- O(N log N)
- O(N)
- O(N^2)
- O(2^N)
2-1. big-O, big-ΞΈ, big-Ξ©
- νκ³μμ μν μκ°μ νκΈ°ν λ μ¬μ©νλ κ°λ
- O(big-O)
- μκ°μ μν
- μκ°μ μνμ΄λ―λ‘ λ°°μ΄μ λͺ¨λ κ°μ μΆλ ₯νλ μκ³ λ¦¬μ¦ $O(N)$ μ λν΄ $O(N^2)$, $O(N^3)$ μΌλ‘ ννν μ μλ€.
- κ·Όλ° κ΅³μ΄ μ΄λ°μμΌλ‘ ννν νμλ μμ β‘οΈ κ°λ μμΌλ‘λ§ μ΄ν΄νμ!
- Ξ©(big-Omega)
- λ±κ° κ°λ νΉμ νν
- λ°°μ΄μ λͺ¨λ κ° μΆλ ₯ μκ³ λ¦¬μ¦
- $Ξ©(N)$ , $Ξ©(logN)$ , $Ξ©(N)$ μΌλ‘ νν κ°λ₯
- μ΄λ€ μκ³ λ¦¬μ¦μΌλ‘ νννλλμ λ°λΌ λ¬λΌμ§ μ μμμ λνλ
- β΄ Ξ© μν μκ°λ³΄λ€ λΉ λ₯Ό μ μλ€!
- ΞΈ(big-theta)
- Oμ Ξ© λ λ€ μλ―Έ
- μ΄λ€ μκ³ λ¦¬μ¦μ μν μκ°μ΄ $O(N)$ μ΄λ©΄μ $Ξ©(N)$ μ΄λΌλ©΄ $ΞΈ(N)$ μ΄λ€.
π‘ μΈν°λ·°μμλ big-Oμ μλ―Έλ ΞΈμ μλ―Έμ κ°κΉμ°λ―λ‘ big-Oμ λν΄ μΈμ λ λ± λ§κ² νκΈ°νμ.
2-2. μ΅μ μ κ²½μ°, μ΅μ μ κ²½μ°, νκ· μ μΈ κ²½μ°
- μκ³ λ¦¬μ¦μ μν μκ°μ μΈ κ°μ§ λ€λ₯Έ λ°©λ²μΌλ‘ λνλΌ μ μλ€.
- e.g. ν΅ μ λ ¬
- βμΆβμ΄ λλ μμ νλλ₯Ό 무μμλ‘ λ½μ λ€, μ΄λ³΄λ€ μμ μμλ€μ μμ, ν° μμλ€μ λ€μ λμ΄λλ‘ μμμ μμΉλ₯Ό λ°κΎΌλ€.
- βλΆλΆ μ λ ¬(partitial sort)β β‘οΈ μΌμͺ½, μ€λ₯Έμͺ½μ μ¬κ·μ μΌλ‘ μ λ ¬ν΄κ°
- μ΅μ μ κ²½μ°
- λͺ¨λ μμ λμΌ : λ¨μν λ°°μ΄ ν μ°¨λ‘ μν
- $O(N)$
- μ΅μ
μ κ²½μ°
- κ°μ₯ ν° μμκ° κ³μν΄μ μΆμ΄ λ¨
- κ³ μ νλ μ€μ΄λ ν¬κΈ°μ λΆλΆ λ°°μ΄λ‘ λλ
- $O(N^2)$
- νκ· μ μΈ κ²½μ°
- μ΅μ κ³Ό μ΅μ μ κ²½μ°κ° κ°λ λ°μ
- $O(N logN)$
- μ΅μ μ κ²½μ°λ μ무 μκ³ λ¦¬μ¦ + νΉμν μ‘°ν©μ ν΅ν΄ μ΄λ»κ²λ $O(1)$λ‘ κ΅¬ν κ°λ₯
- β΄ λ±ν λ Όμ λμμ΄ μλ!
- λλΆλΆμ κ²½μ° μ΅μ μ κ²½μ°μ νκ· μ μΈ κ²½μ°κ° κ°λ€.
- μ΅μ /μ΅μ
/νκ· μ κ²½μ° β big-O/ΞΈ/Ξ©
- μλ¬΄λ° κ΄λ ¨μ± μμ
μ΅μ /μ΅μ /νκ· μ κ²½μ°
: μ΄λ€ μ λ ₯ λλ μν©μμ big-Oλ‘ ννbig-O/ΞΈ/Ξ©
: κ°κ° μν, νν, λ± λ§λ μν μκ°μ μλ―Έ
3. Space Complexity
- μκ³ λ¦¬μ¦μμλ μκ°λΏ μλλΌ λ©λͺ¨λ¦¬ λν μ κ²½ μ¨μΌ νλ€.
- βοΈμ¬κ· νΈμΆμμ μ¬μ©νλ μ€ν κ³΅κ° λν κ³΅κ° λ³΅μ‘λμ ν¬ν¨λλ€.
1
2
3
4
5
6
int sum(int n) {
if (n <= 0) {
return 0;
}
return n + sum(n - 1);
}
ν΄λΉ μ½λλ νΈμΆλ λλ§λ€ μ€νμ κΉμ΄κ° κΉμ΄μ§λ€.
μ λΆ νΈμΆ μ€νμ λν΄μ§κ³ μ€μ λ©λͺ¨λ¦¬ 곡κ°μ μ‘μ λ¨Ήλλ€.
But, λ¨μ§ nλ² νΈμΆνλ€κ³ ν΄μ $O(n)$ 곡κ°μ μ¬μ©νμ§ μλλ€.
1
2
3
4
5
6
7
8
9
10
int pairSumSequence(int n){
int sum = 0;
for (int i = 0; i < n; i++){
sum += pairSum(i, i + 1);
}
return sum;
}
int pairSum(int a, int b) {
return a + b;
}
- ν¨μλ€μ΄ νΈμΆ μ€νμ λμμ μ‘΄μ¬νμ§ μμΌλ―λ‘ O(1) 곡κ°λ§ μ¬μ©νλ€.
4. Drop the Constants
- big-Oλ λ¨μν μ¦κ°νλ λΉμ¨μ λνλ΄λ κ°λ
- νΉμ μ λ ₯μ νν΄, O(N)μ΄ O(1)λ³΄λ€ λΉ λ₯΄κ² λμν μ μμ!
- β΄ μν μκ°μμ μμνμ 무μνλ€!
- βμν μκ°μ΄ μ΄λ»κ² λ³ννλ μ§λ₯Ό ννν΄μ£Όλ λꡬβμ΄λ―λ‘ λ³΅μ‘ν μ°μ°μ λΆμνκ±°λ μΈλΆμ¬νμ κ³ λ €ν νμλ μλ€.
- $O(n)$ μ΄ μΈμ λ $O(2N)$ λ³΄λ€ λμ κ²μ μλλΌλ μ¬μ€λ§ μκ³ μμ.
5. Drop the Non-Dominant Terms
- $O(N^2 + N)$ μμ λ λ²μ§Έ Nμ νΉλ³ν μ€μν νμ΄ μλλ€.
- β΄ μμμμ μ§λ°°μ μ΄μ§ μμ νμ 무μν΄λ λλ€.
- big-O μκ° μ¦κ°μ¨ κ·Έλν
6. Multi-Part Algorithms: Add vs. Multiply
- λ§μ μν μκ°μ κ²½μ°
1
2
3
4
5
6
for (int a : arrA) {
print(a);
}
for (int b : arrB) {
print(b);
}
- κ³±μ μν μκ°μ κ²½μ°
1
2
3
4
5
for (int a : arrA) {
for (int b : arrB) {
print(a + "," + b);
}
}
- A + B : βA μΌμ λͺ¨λ λλ§μΉ νμ B μΌμ μννλΌβ
- A * B : βA μΌμ ν λλ§λ€ B μΌμ μννλΌβ
7. Amortized Time
- ArrayList (λμ κ°λ³ ν¬κΈ° λ°°μ΄)
- λ°°μ΄μ μν μ ν¨κ³Ό λμμ ν¬κΈ°κ° μμ λ‘κ² μ‘°μ λλ μλ£κ΅¬μ‘°
- μμ μ½μ μ νμμ λ°λΌ λ°°μ΄μ ν¬κΈ°λ₯Ό μ¦κ°μν¬ μ μμΌλ―λ‘ ArrayListμ 곡κ°μ΄ λ°λ₯λ μΌ X
- λ°°μ΄μ μ©λμ΄ κ½ μ°Όμ λ, ArrayList ν΄λμ€λ κΈ°μ‘΄λ³΄λ€ ν¬κΈ°κ° λ λ°° λ ν° λ°°μ΄μ λ§λ λ€μ μ΄μ λ°°μ΄μ λͺ¨λ μμλ₯Ό μ λ°°μ΄λ‘ 볡μ¬νλ€.
- μ΄λ μ½μ μ°μ° μκ° : $O(N)$
- β΅ κΈ°μ‘΄μ λͺ¨λ μμλ₯Ό μ λ°°μ΄λ‘ 볡μ¬ν΄μΌνκΈ° λλ¬Έ
- But, λλ€μμ κ²½μ°μλ λ°°μ΄μ κ°μ© 곡κ°μ΄ μ‘΄μ¬νκ³ μ΄λμ μ½μ μ°μ°μ $O(1)$μ΄ μμλλ€.
μ΄λ¬ν λ κ°μ§μ μ°μ° (βλ°°μ΄μ΄ κ½ μ°Όμ λ μ½μ β, βμΌλ°μ μΈ μ½μ β)μ ν¬ν¨ν μ 체 μν μκ°μ λ°μ§λ€.
- λΆν μν : μ΅μ μ κ²½μ°λ κ°λ λ°μνμ§λ§ ν λ² λ°μνλ©΄ κ·Έ νλ‘ κ½€ μ€λ«λμ λνλμ§ μμ
- β΄ μ΄λ¬ν κ²½μ°μ μν μκ°μ $O(1)$ μ΄λ€.
8. Log N Runtimes
- μ΄μ§ νμ
- Nκ°μ μ λ ¬λ μμκ° λ€μ΄ μλ λ°°μ΄μμ μμ xλ₯Ό μ°Ύμ λ μ¬μ©
- μμ xμ λ°°μ΄μ μ€κ°κ°μ λΉκ΅ ν κ°μΌλ©΄ λ°ν
- x < μ€κ°κ°μ κ²½μ°, μΌμͺ½ νμ
- x > μ€κ°κ°μ κ²½μ°, μ€λ₯Έμͺ½ νμ
- μ²μμλ μμ Nκ°κ° λ€μ΄μλ λ°°μ΄μμ μμ
- ν λ¨κ³ μ΄ν, νμν΄μΌν μμμ κ°μκ° $N/2$λ‘ μ€μ΄λ¦
- λ λ¨κ³ μ΄ν, νμν΄μΌν μμμ κ°μκ° $N/4$λ‘ μ€μ΄λ¦
- β΄ λ°λΌμ μ΄ μν μκ°μ λͺ λ¨κ³ λ§μ 1μ΄ λλμ§μ λ°λΌ κ²°μ λλ€.
$2^k = N$ λ₯Ό λ§μ‘±νλ $k$ κ° λμΆ β‘οΈ λ‘κ·Έ(log)λ₯Ό μ¬μ©νμ¬ νν
- μ΄λ€ λ¬Έμ μμ μμμ κ°μκ° μ λ°μ© μ€μ΄λ λ€λ©΄ κ·Έ λ¬Έμ μ μν μκ°μ $O(log N)$μ΄ λ κ°λ₯μ±μ΄ ν¬λ€.
- κ· ν μ΄μ§ νμ νΈλ¦¬μμλ 맀 λ¨κ³λ§λ€ μμμ λμ λΉκ΅ ν μ’μ°λ‘ λ΄λ €κ°λ―λ‘ μ΄λλ $O(log N)$μ μν μκ°μ΄ μμλλ€.
- π€ κ·Έλ λ€λ©΄ big-Oμμ λ‘κ·Έμ λ°μ?
- κ³ λ €ν νμ X (μνμ μΈ κ°λ )
- π‘ λ°μ΄ λ€λ₯Έ λ‘κ·Έλ μμν λ§νΌ μ°¨μ΄κ° λλ―λ‘ big-O ννμμμλ λλΆλΆ λ‘κ·Έμ λ°μ 무μνλ€.
9. Recursive Runtimes
- νΌλ³΄λμΉ μμ΄ μ½λ
1
2
3
4
5
6
int f(int n) {
if (n <= 1) {
return 1;
}
return f(n - 1) + f(n - 1);
}
- μ 체 λ Έλμ κ°μ : $2^0 + 2^1 + 2^2 + 2^3 + β¦ + 2^N (= 2^{N+1} - 1)$
- β΄ μ¬κ· ν¨μμμ μν μκ°
- $O(λΆκΈ°^{κΉμ΄})$
- κ³΅κ° λ³΅μ‘λ : $O(N)$
- νΉμ μκ°μ μ¬μ©νλ 곡κ°μ ν¬κΈ°λ $O(N)$ μ΄λ€.
- μ 체 λ Έλμ κ°μ : $O(2^N)$
πΒ 1. Harvard CS50 - Asymptotic Notation
- νλ‘κ·Έλ¨μ λ°νμμ΄ μ κ·Όμ μΌλ‘ μΌλ§λ 빨리 μ¦κ°νλμ§ λΆμνλ λ°©λ²
- μ λ ₯ ν¬κΈ°κ° 무νλλ‘ μ¦κ°ν¨μ λ°λΌ ν¬κΈ°κ° 10μΈ λ°°μ΄κ³Ό λΉκ΅νμ¬ ν¬κΈ°κ° 100μΈ λ°°μ΄μ μ λ ¬νλ κ²
ex1. λ¬Έμμ΄μ κ°μλ₯Ό μΈλ λ°©λ²
- λ¬Έμμ΄μ λ¬Έμ μ βnβμ λν΄ μ ν μκ°μΌλ‘ μ€ν
- λ¬Έμ μλ₯Ό λ리면 λ°νμμ μ λ ₯ κΈΈμ΄μ λ°λΌ μ νμ μΌλ‘ μ¦κ°
- But, λ§μ½ λ¬Έμμ΄μ κΈΈμ΄λ₯Ό κ³μ°νμ¬ νλμ λ³μμ μ μ₯ν΄λλ κ²½μ° κ³ λ €
len
μ΄λΌλ λ³μμ λ¬Έμμ΄μ κΈΈμ΄λ₯Ό κ³μ°νμ¬ λ£μ΄λλλ€.
βοΈ Asymptotic Complexity βοΈ
- μ΄λ λ¬Έμμ΄μ κΈΈμ΄μ μ ν μκ΄μμ΄ νλ‘κ·Έλ¨ μ€ν μλμ μ ν μν₯μ λ―ΈμΉμ§ μλλ€.
- 1μμ λ¬Έμμ΄κ³Ό 1000μμ λ¬Έμμ΄μμ λκ°μ΄ λΉ λ₯΄κ² μ€ν
- λ³λμ λ©λͺ¨λ¦¬ μ°¨μ§ λΌλ λ¨μ λ°μ
- λ¨κ³ μμ κ΄κ³μμ΄ μ λ ₯ ν¬κΈ°μ λ°λΌ λ³κ²½λμ§ μμΌλ©΄ μ¬μ ν O(1)λ‘ λνλ΄λ μ κ·Όμ μΌλ‘ μΌμ
λ€μν Big-O μκ³ λ¦¬μ¦
\[O(n^2)\]- \(O(n^2)\) κ° \(O(n)\) μ λΉν΄ μ λ ₯ λ°μ΄ν°μ μκ° μ μ λλ λ λΉ λ₯Ό μ μμ§λ§ λ°μ΄ν°κ° λ§μμ§λ©΄ κ·Έ μ°¨μ΄κ° 컀μ§λ€.
- λνμ μΈ μμ : μ΄μ§νμ
- μ΄λ―Έ μ λ ¬λ μμμ λν νμ μν
- κ° μμ μμ λ°°μ΄μ ν¬κΈ°λ₯Ό μ λ°μΌλ‘ μ€μΈλ€.
- λ°°μ΄μ ν¬κΈ°λ₯Ό λλ°° ν€μ°λ©΄ ν΄λΉ μ½λμ 1 Chunkλ§νΌ μ€ν μκ°μ΄ λμ΄λλ€.
- λͺ©λ‘μ μ€κ° μμλ₯Ό νμΈν λ€μ λΆν νλ€. -> λμμκ° \(O(log n)\) μμ μλνλ€.
- best-case : μ²μμ λ°λ‘ μ°Ύκ³ μνλ μμλ₯Ό μ°Ύλ κ²½μ°
- worst-case : μ΅νμ κ²½μ°μ μ°Ύκ³ μνλ μμλ₯Ό μ°Ύλ κ²½μ°
βοΈ λ°νμμ μνκ³Ό νν βοΈ