16. νμμ μκ³ λ¦¬μ¦ (Greedy Algorithms) Codility Lesson νκ΅μ΄ μ 리본 (JavaScript ver.)
νμμ μκ³ λ¦¬μ¦(Greedy Algorithm)μ΄λ?
νμμ μκ³ λ¦¬μ¦μ κ° λ¨κ³μμ κ°μ₯ μ΅μ μ μ νμ νλ λ°©μμΌλ‘ μ΅μ ν΄λ₯Ό μ°Ύλ λ°©λ² μ΄λ€. μ 체 μ΅μ ν΄λ₯Ό κ³ λ €νμ§ μκ³ , λ§€ μκ° μ΅μ μ μ νμ νκΈ° λλ¬Έμ ꡬνμ΄ κ°λ¨νμ§λ§, νμ μ΅μ ν΄λ₯Ό 보μ₯νλ κ²μ μλλ€.
νμμ μκ³ λ¦¬μ¦μ΄ μ μ©λ μ μλ λνμ μΈ λ¬Έμ λ€:
- λμ κ±°μ€λ¦λ λ¬Έμ (Coin Change Problem)
- νμμ€ λ°°μ λ¬Έμ (Activity Selection Problem)
- λ°°λ λ¬Έμ (Knapsack Problem)
- μμ μ€μΌμ€λ§ λ¬Έμ (Activity Selection)
- μ΅μ μ μ₯ νΈλ¦¬ (MST, Minimum Spanning Tree)
- ννλ§ μ½λ© (Huffman Coding)
νμ μκ³ λ¦¬μ¦μ νΉμ§
- λΉ λ₯Έ μ€ν μκ°: O(n log n) λλ O(n)λ‘ ν΄κ²° κ°λ₯
- κ΅μμ μ΅μ ν΄ κΈ°λ°: νμ¬ μνμμ κ°μ₯ μ’μ μ νμ νλ€.
- μ΅μ ν΄λ₯Ό νμ 보μ₯νμ§ μμ: λμ κ±°μ€λ¦λ λ¬Έμ μ²λΌ μΌλΆ κ²½μ°μλ μ΅μ ν΄λ₯Ό ꡬν μ μλ€.
4. νμμ μκ³ λ¦¬μ¦μ νκ³
νμμ μκ³ λ¦¬μ¦μ λ§€ μκ° μ΅μ μ μ νμ νμ§λ§, νμ μ 체 μ΅μ ν΄λ₯Ό 보μ₯νλ κ²μ μλλ€. λ°λΌμ λ€μκ³Ό κ°μ κ²½μ°μλ μ¬μ©νκΈ° μ΄λ ΅λ€:
- μ΅μ λΆλΆ ꡬ쑰(Otimal Substructure) κ° μλ κ²½μ° (μ: λ°°λ λ¬Έμ , μΌλΆ λμ κ±°μ€λ¦λ λ¬Έμ )
- κ²°μ ν΄μΌ ν μμλ€μ΄ μλ‘ μν₯μ λ―ΈμΉλ κ²½μ°
μ΄λ¬ν λ¬Έμ μμλ λμ νλ‘κ·Έλλ°(DP)μ΄λ λ°±νΈλνΉ(Backtracking) κ°μ λ€λ₯Έ λ°©λ²μ΄ νμν μ μλ€.
1. O(n) μκ° λ³΅μ‘λμ κ±°μ€λ¦λ λ¬Έμ ν΄κ²°
κ±°μ€λ¦λ λ¬Έμ λ μ£Όμ΄μ§ λμ λ€λ‘ νΉμ κΈμ‘μ μ΅μ κ°μμ λμ μΌλ‘ λ§λλ λ¬Έμ μ΄λ€. νμμ μκ³ λ¦¬μ¦μ κ°μ₯ ν° λμ λΆν° μ ννλ λ°©μμΌλ‘ ν΄κ²°ν μ μλ€.
JavaScript μ½λ:
function coinChange(coins, amount) {
coins.sort((a, b) => b - a); // λ΄λ¦Όμ°¨μ μ λ ¬
let count = 0;
for (let coin of coins) {
while (amount >= coin) {
amount -= coin;
count++;
}
}
return amount === 0 ? count : -1;
}
μκ° λ³΅μ‘λ: O(n) (λμ κ°μλ§νΌ λ°λ³΅)
μ£Όμ: μ΄ λ°©λ²μ νμ μ΅μ ν΄λ₯Ό 보μ₯νμ§ μλλ€. μλ₯Ό λ€μ΄, λμ μ΄ [1, 3, 4]μ΄κ³ amount = 6μΌ λ, νμμ μ κ·Όλ²μ [4, 1, 1]μ μ ννμ§λ§, μ΅μ ν΄λ [3, 3]μ΄λ€.
2. O(n log n) μκ° λ³΅μ‘λμ νμμ€ λ°°μ λ¬Έμ
νμμ€ λ°°μ λ¬Έμ λ κ°λ₯ν ν λ§μ νμλ₯Ό μμ©νκΈ° μν΄, νμκ° κ²ΉμΉμ§ μλλ‘ λ°°μ νλ λ¬Έμ μ΄λ€. μ’ λ£ μκ°μ΄ κ°μ₯ λΉ λ₯Έ νμλΆν° μ ννλ©΄ μ΅μ ν΄λ₯Ό 보μ₯ν μ μλ€.
JavaScript μ½λ:
function maxMeetings(start, end) {
let n = start.length;
let meetings = [];
for (let i = 0; i < n; i++) {
meetings.push([start[i], end[i]]);
}
meetings.sort((a, b) => a[1] - b[1]); // μ’
λ£ μκ° κΈ°μ€ μ λ ¬
let count = 0, lastEnd = 0;
for (let [s, e] of meetings) {
if (s >= lastEnd) {
count++;
lastEnd = e;
}
}
return count;
}
μκ° λ³΅μ‘λ: O(n log n) (μ λ ¬ ν μ ν νμ)
3. O(E log V) μκ° λ³΅μ‘λμ λ€μ΅μ€νΈλΌ μκ³ λ¦¬μ¦
λ€μ΅μ€νΈλΌ μκ³ λ¦¬μ¦(Dijkstra’s Algorithm)μ κ°μ€μΉκ° μλ κ·Έλνμμ μΆλ°μ μΌλ‘λΆν° λͺ¨λ μ μ κΉμ§μ μ΅λ¨ κ²½λ‘λ₯Ό μ°Ύλ μκ³ λ¦¬μ¦ μ΄λ€. νμμ λ°©λ²μ μ¬μ©νμ¬ λ§€ λ¨κ³μμ μ΅λ¨ 거리λ₯Ό μ ννλ€.
JavaScript μ½λ:
class PriorityQueue {
constructor() {
this.queue = [];
}
enqueue(value, priority) {
this.queue.push({ value, priority });
this.queue.sort((a, b) => a.priority - b.priority);
}
dequeue() {
return this.queue.shift().value;
}
isEmpty() {
return this.queue.length === 0;
}
}
function dijkstra(graph, start) {
let distances = {};
let pq = new PriorityQueue();
for (let node in graph) {
distances[node] = Infinity;
}
distances[start] = 0;
pq.enqueue(start, 0);
while (!pq.isEmpty()) {
let current = pq.dequeue();
for (let neighbor in graph[current]) {
let newDist = distances[current] + graph[current][neighbor];
if (newDist < distances[neighbor]) {
distances[neighbor] = newDist;
pq.enqueue(neighbor, newDist);
}
}
}
return distances;
}
μκ° λ³΅μ‘λ: O(E log V) (μ°μ μμ νλ₯Ό μ΄μ©ν ꡬν)
4. μΉ΄λ λ¬Έμ (Canoeist Problem)
λ¬Έμ
무κ²κ° λ€λ₯Έ nλͺ μ μΉ΄λ μ μκ° μκ³ , κ° μΉ΄λμλ μ΅λ λ λͺ κΉμ§ ν μ μλ€. λͺ¨λ μ μλ₯Ό μ΅μνμ μΉ΄λμ λ°°μΉνλ κ²μ΄ λͺ©νμ΄λ€.
μ κ·Ό λ°©λ²
- κ°μ₯ λ¬΄κ±°μ΄ μ μ(heavy)λ₯Ό μ°Ύκ³ , ν¨κ» ν μ μλ κ°μ₯ λ¬΄κ±°μ΄ κ°λ²Όμ΄ μ μ(light)λ₯Ό μ°Ύλλ€.
- λ¬΄κ±°μ΄ μ μμ κ°λ²Όμ΄ μ μλ₯Ό ν¨κ» νμ΄λ€.
- μ κ³Όμ μ΄ λΆκ°λ₯νλ©΄ λ¬΄κ±°μ΄ μ μλ§ λ°λ‘ νμ΄λ€.
JavaScript μ½λ (νμ μκ³ λ¦¬μ¦)
function greedyCanoeist(weights, maxWeight) {
weights.sort((a, b) => a - b); // λ¬΄κ² κΈ°μ€ μ λ ¬
let canoes = 0;
let i = 0, j = weights.length - 1;
while (i <= j) {
if (weights[i] + weights[j] <= maxWeight) {
i++; // κ°λ²Όμ΄ μ¬λκ³Ό ν¨κ» νμ΄λ€.
} j--; // λ¬΄κ±°μ΄ μ¬λμ 무쑰건 νμ
canoes++;
}
return canoes;
}
μκ° λ³΅μ‘λ: O(n log n) (μ λ ¬) + O(n) (νμ) = O(n log n)
5. νμ μκ³ λ¦¬μ¦μ μ¦λͺ (Greedy Algorithm Proof)
νμ μκ³ λ¦¬μ¦μ΄ νμ μ΅μ ν΄λ₯Ό 보μ₯νλ €λ©΄, μ νν κ²°μ μ΄ μ 체 λ¬Έμ μμλ μ΅μ ν΄λ₯Ό 보μ₯ν΄μΌ νλ€. μ΄λ₯Ό μνμ κ·λ©λ²μΌλ‘ μ¦λͺ ν μ μλ€.
- 첫 λ²μ§Έ μ νμ΄ μ΅μ ν΄μ μΌλΆλΌλ©΄, λλ¨Έμ§ λ¬Έμ λ μ΅μ ν΄λ₯Ό ν¬ν¨ν μ μμ΄μΌ νλ€.
- κΈ°μ‘΄μ μ΅μ ν΄μμ 첫 λ²μ§Έ μ νμ λ€λ₯Έ κ°μΌλ‘ λ°κΎΈμ΄λ λμΌν μ±λ₯μ μ μ§ν μ μμ΄μΌ νλ€.
- λ§μ½ λ°κΏ¨μ λ λ λμ ν΄λ΅μ΄ λμ¨λ€λ©΄, νμμ μ νμ΄ μλͺ»λμμμ μλ―Ένλ€.
μ μ¦λͺ μ΄ μ±λ¦½νλ©΄ νμ μκ³ λ¦¬μ¦μ μ¬μ©ν΄λ μ΅μ ν΄λ₯Ό 보μ₯ν μ μλ€.