TIL47: [์๋ฃ๊ตฌ์กฐ/์๊ณ ๋ฆฌ์ฆ] ์ฝ๋ฉ ํ ์คํธ ์ค๋น
์ค๋์ ์๋ฃ๊ตฌ์กฐ์ ์๊ณ ๋ฆฌ์ฆ์ ํ์ตํ์ต๋๋ค. ์น์ 2์์์ ์๋ฃ๊ตฌ์กฐ์ ์๊ณ ๋ฆฌ์ฆ์ ๊ณต๋ถํ ๋, BFS์ DFS๊ฐ ์ด๋ ค์ ์ด์ ์์ํ๊ธฐ ์ ๋ถํฐ ์ข ๊ฒ์ ๋จน์ ์ํ์์ต๋๋ค. ํ์ง๋ง ์ด์ ์ Toy Problem๊ณผ ์ฝํ๋ฆฟ์ผ๋ก ์ฌ๋ฌ๋ฒ ํ๋ค์ด๋ดค์ด์ ๊ทธ๋ฐ์ง ์๊ฐ์ธ๋ก ๊ด์ฐฎ์์ต๋๋คใ ใ
์๊ฐ ๋ณต์ก๋(Time Complexity)
๋ค์์ ์ธ๊ฐ์ง ๊ฒฝ์ฐ์ ๊ฐ์ด ์๊ฐ ๋ณต์ก๋๋ฅผ ํํํ ์ ์์ต๋๋ค.
- ์ต์์ ๊ฒฝ์ฐ : ์ค๋ฉ๊ฐ ํ๊ธฐ๋ฒ (Big-Ω Notation)
- ํ๊ท ์ ๊ฒฝ์ฐ : ์ธํ ํ๊ธฐ๋ฒ (Big-θ Notation)
- ์ต์ ์ ๊ฒฝ์ฐ : ๋น ์ค ํ๊ธฐ๋ฒ (Big-O Notation)
function O_n(n) {
for (let i = 0; i < n; i++) {
// do something for 1 second
}
}
function O_2n(n) {
for (let i = 0; i < 2n; i++) {
// do something for 1 second
}
}
์ฒซ๋ฒ์งธ ํจ์๋ ์ ๋ ฅ๊ฐ์ด 1 ์ฆ๊ฐํ ๋๋ง๋ค ์ฝ๋์ ์คํ ์๊ฐ์ด 1์ด์ฉ ์ฆ๊ฐํฉ๋๋ค. ๋๋ฒ์งธ ํจ์๋ ์ ๋ ฅ๊ฐ์ด 1 ์ฆ๊ฐํ ๋๋ง๋ค ์ฝ๋์ ์คํ ์๊ฐ์ด 2์ด์ฉ ์ฆ๊ฐํฉ๋๋ค. ์คํ์๊ฐ์ ์ฐจ์ด๊ฐ ์ด๋ ๊ฒ ์์ง๋ง ๋๋ฒ์งธ ํจ์ ๋ํ ์ฒซ๋ฒ์งธ ํจ์์ฒ๋ผ Big-O ํ๊ธฐ๋ฒ์ผ๋ก O(n)์ผ๋ก ํ๊ธฐํฉ๋๋ค. ์ ๋ ฅ๊ฐ์ด ์ปค์ง๋ฉด ์ปค์ง์๋ก ๊ณ์(n ์์ ์๋ ์)์ ์๋ฏธ(์ํฅ๋ ฅ)๊ฐ ์ ์ ํด์๋๊ธฐ ๋๋ฌธ์, ๊ฐ์ ๋น์จ๋ก ์ฆ๊ฐํ๊ณ ์๋ค๋ฉด 2๋ฐฐ, 5๋ฐฐ, 10๋ฐฐ๋ก ์ฆ๊ฐํ๋๋ผ๋ O(n)์ผ๋ก ํ๊ธฐํฉ๋๋ค.
- ๊ฐ์ฅ ๋น ๋ฅธ/๋๋ฆฐ ์๊ฐ ๋ณต์ก๋๋ ๋ฌด์์ผ๊น์?
๊ฐ์ฅ ๋น ๋ฅธ ์๊ฐ ๋ณต์ก๋๋ O(1)์ด๊ณ , ๊ฐ์ฅ ๋๋ฆฐ ์๊ฐ ๋ณต์ก๋๋ O(2์ n์ ๊ณฑ) ์ ๋๋ค. - ํจ์จ์ ์ธ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌ์ฑํ๋ค ํจ์ ๋ฌด์์ ์๋ฏธํ ๊น์?
์ ๋ ฅ๊ฐ์ ์ฆ๊ฐ์ ๋ฐ๋ผ ์ฆ๊ฐํ๋ ์๊ฐ๋น์จ์ ์ต์ํํ ๊ฒ์ ๋งํฉ๋๋ค. - ์๊ฐ ๋ณต์ก๋๋ A์ B์ ๋น๋กํจ์ด ์ด๋ ์ ๋์ธ์ง๋ฅผ ๋ํ๋
๋๋ค. A์ B๋ ๋ฌด์์ผ๊น์?
์ ๋ ฅ๊ฐ๊ณผ ์คํ๋๋ ์๊ฐ์ ๋น๋กํจ์ด ์ด๋ ์ ๋์ธ์ง๋ฅผ ๋ํ๋ ๋๋ค.
let i = n;
while (parseInt(i) > 0) {
i = i / 2;
}
์ ์ฝ๋์ ์๊ฐ ๋ณต์ก๋๋ O(log n) ์ ๋๋ค.
for (let i = 0; i < n; i++) {
i *= k;
}
์ ์ฝ๋์ ์๊ฐ ๋ณต์ก๋๋ O(log k n)๋๋ O(log n) ์ ๋๋ค.
Greedy Algorithm (ํ์ ์๊ณ ๋ฆฌ์ฆ)
ํ์ ์๊ณ ๋ฆฌ์ฆ์ ์๋ 2๊ฐ์ง์ ์กฐ๊ฑด์ ์ฑ๋ฆฝํด์ผ ์ ์๋ํฉ๋๋ค.
1. ํ์์ ์ ํ ์์ฑ (Greedy Choice Property): ์์ ์ ํ์ด ์ดํ์ ์ ํ์ ์ํฅ์ ์ฃผ์ง ์๋๋ค.
2. ์ต์ ๋ถ๋ถ ๊ตฌ์กฐ (Optimal Substructure): ๋ฌธ์ ์ ๋ํ ์ต์ข ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๋ถ๋ถ ๋ฌด์ ์ ๋ํ ์ต์ ๋ฌธ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ผ๋ก ๊ตฌ์ฑ๋๋ค.
ํ์ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ด ๋จ๊ณ์ ์ผ๋ก ๊ตฌ๋ถํ ์ ์์ต๋๋ค.
1. ์ ํ ์ ์ฐจ (Selection Procedure): ํ์ฌ ์ํ์์์ ์ต์ ์ ํด๋ต์ ์ ํํฉ๋๋ค.
2. ์ ์ ์ฑ ๊ฒ์ฌ (Feasibility Check): ์ ํ๋ ํด๊ฐ ๋ฌธ์ ์ ์กฐ๊ฑด์ ๋ง์กฑํ๋์ง ๊ฒ์ฌํฉ๋๋ค.
3. ํด๋ต๊ฒ์ฌ (Solution Check): ์๋์ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋์๋์ง ๊ฒ์ฌํ๊ณ , ํด๊ฒฐ๋์ง ์์๋ค๋ฉด ์ ํ ์ ์ฐจ๋ก ๋์๊ฐ ์์ ๊ณผ์ ์ ๋ฐ๋ณตํฉ๋๋ค.
ํ์ ์๊ณ ๋ฆฌ์ฆ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ณผ์ ์์ ๋งค ์๊ฐ, ์ต์ ์ด๋ผ ์๊ฐ๋๋ ํด๋ต์ ์ฐพ์ผ๋ฉฐ, ์ด๋ฅผ ํ ๋๋ก ์ต์ข ๋ฌธ์ ์ ํด๋ต์ ๋๋ฌํ๋ ๋ฌธ์ ํด๊ฒฐ ๋ฐฉ์์ ๋๋ค. ๊ทธ๋ฌ๋ ํญ์ ์ต์ ์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฅํ์ง๋ ๋ชปํฉ๋๋ค.
Dynamic Programming (DP; ๋์ ๊ณํ๋ฒ)
์ฃผ์ด์ง ๋ฌธ์ ๋ฅผ ์ฌ๋ฌ ๊ฐ์ ํ์ ๋ฌธ์ ๋ก ๋๋์ด ํ๊ณ , ํ์ ๋ฌธ์ ๋ค์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๊ฒฐํฉํ์ฌ ์ต์ข ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฌธ์ ํด๊ฒฐ ๋ฐฉ์์ ๋๋ค.
์ฆ, ํฐ ๋ฌธ์ ๋ฅผ ์์ ๋ฌธ์ ๋ก ๋๋ ์ ์๊ณ , ์ด ์์ ๋ฌธ์ ๊ฐ ์ค๋ณตํด์ ๋ฐ๊ฒฌ๋์ด์ผ ํฉ๋๋ค.
๋ํ, ์์ ๋ฌธ์ ์์ ๊ตฌํ ์ ๋ต์ ๊ทธ๊ฒ์ ํฌํจํ๋ ํฐ ๋ฌธ์ ์์๋ ๋์ผํด์ผ ํฉ๋๋ค.
DP์๋ ํฌ๊ฒ ๋๊ฐ์ง ๋ฐฉ์์ผ๋ก ํ ์ ์์ต๋๋ค.
Recursion + Memoization (Top-down ๋ฐฉ์)
Memoization (๋ฉ๋ชจํ): ์ปดํจํฐ ํ๋ก๊ทธ๋จ์ด ๋์ผํ ๊ณ์ฐ์ ๋ฐ๋ณตํด์ผํ ๋, ์ด์ ์ ๊ณ์ฐ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํจ์ผ๋ก์จ ๋์ผํ ๊ณ์ฐ์ ๋ฐ๋ณต ์ํ์ ์ ๊ฑฐํด ํ๋ก๊ทธ๋จ ์คํ ์๋๋ฅผ ๋น ๋ฅด๊ฒ ํ ์ ์์ต๋๋ค.
Iteration + Tabulation (Botom-up ๋ฐฉ์)
Top-down ๋ฐฉ์๋ณด๋ค ํจ์ ์คํ์๊ฐ์ด ๋ ์ ๊ฒ ๋ญ๋๋ค.
ํฌ๋กฌ ๊ฐ๋ฐ์ ๋๊ตฌ์์ ํจ์ ์คํ ์๊ฐ ์ธก์ ๋ฐฉ๋ฒ
var t0 = performance.now();
fib(50); // ์ฌ๊ธฐ์์ ํจ์ ์คํ์ ์์ผ์ฃผ์ธ์
var t1 = performance.now();
console.log("runtime: " + (t1 - t0) + 'ms')