λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

Algorithm

[Algorithm] λͺ…μ˜ˆμ˜ μ „λ‹Ή(1)

문제 μ„€λͺ…


"λͺ…μ˜ˆμ˜ μ „λ‹Ή"μ΄λΌλŠ” TV ν”„λ‘œκ·Έλž¨μ—μ„œλŠ” λ§€μΌ 1λͺ…μ˜ κ°€μˆ˜κ°€ λ…Έλž˜λ₯Ό λΆ€λ₯΄κ³ , μ‹œμ²­μžλ“€μ˜ λ¬Έμž νˆ¬ν‘œμˆ˜λ‘œ κ°€μˆ˜μ—κ²Œ μ μˆ˜λ₯Ό λΆ€μ—¬ν•©λ‹ˆλ‹€. λ§€μΌ μΆœμ—°ν•œ κ°€μˆ˜μ˜ μ μˆ˜κ°€ μ§€κΈˆκΉŒμ§€ μΆœμ—° κ°€μˆ˜λ“€μ˜ μ μˆ˜ μ€‘ μƒμœ„ k번째 μ΄λ‚΄μ΄λ©΄ ν•΄λ‹Ή κ°€μˆ˜μ˜ μ μˆ˜λ₯Ό λͺ…μ˜ˆμ˜ μ „λ‹Ήμ΄λΌλŠ” λͺ©λ‘μ— μ˜¬λ € κΈ°λ…ν•©λ‹ˆλ‹€. μ¦‰ ν”„λ‘œκ·Έλž¨ μ‹œμž‘ μ΄ν›„ μ΄ˆκΈ°μ— kμΌκΉŒμ§€λŠ” λͺ¨λ“  μΆœμ—° κ°€μˆ˜μ˜ μ μˆ˜κ°€ λͺ…μ˜ˆμ˜ μ „당에 μ˜€λ₯΄κ²Œ λ©λ‹ˆλ‹€. k일 λ‹€μŒλΆ€ν„°λŠ” μΆœμ—° κ°€μˆ˜μ˜ μ μˆ˜κ°€ κΈ°μ‘΄μ˜ λͺ…μ˜ˆμ˜ μ „λ‹Ή λͺ©λ‘μ˜ k번째 μˆœμœ„μ˜ κ°€μˆ˜ μ μˆ˜λ³΄λ‹€ λ” λ†’μœΌλ©΄, μΆœμ—° κ°€μˆ˜μ˜ μ μˆ˜κ°€ λͺ…μ˜ˆμ˜ μ „당에 μ˜€λ₯΄κ²Œ λ˜κ³  κΈ°μ‘΄μ˜ k번째 μˆœμœ„μ˜ μ μˆ˜λŠ” λͺ…μ˜ˆμ˜ μ „λ‹Ήμ—μ„œ λ‚΄λ €μ˜€κ²Œ λ©λ‹ˆλ‹€.

이 ν”„λ‘œκ·Έλž¨μ—μ„œλŠ” 맀일 "λͺ…μ˜ˆμ˜ μ „λ‹Ή"의 μ΅œν•˜μœ„ 점수λ₯Ό λ°œν‘œν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, k = 3이고, 7일 λ™μ•ˆ μ§„ν–‰λœ κ°€μˆ˜μ˜ μ μˆ˜κ°€ [10, 100, 20, 150, 1, 100, 200]이라면, λͺ…μ˜ˆμ˜ μ „λ‹Ήμ—μ„œ λ°œν‘œλœ μ μˆ˜λŠ” μ•„λž˜μ˜ κ·Έλ¦Όκ³Ό 같이 [10, 10, 10, 20, 20, 100, 100]μž…λ‹ˆλ‹€.

λͺ…μ˜ˆμ˜ μ „λ‹Ή λͺ©λ‘μ˜ 점수의 개수 k, 1일뢀터 λ§ˆμ§€λ§‰ λ‚ κΉŒμ§€ μΆœμ—°ν•œ κ°€μˆ˜λ“€μ˜ 점수인 scoreκ°€ μ£Όμ–΄μ‘Œμ„ λ•Œ, 맀일 λ°œν‘œλœ λͺ…μ˜ˆμ˜ μ „λ‹Ήμ˜ μ΅œν•˜μœ„ 점수λ₯Ό returnν•˜λŠ” solution ν•¨μˆ˜λ₯Ό μ™„μ„±ν•΄μ£Όμ„Έμš”.

μ œν•œμ‚¬ν•­

3 ≤ k ≤ 100
7 ≤ score의 κΈΈμ΄ ≤ 1,000
0 ≤ score[i] ≤ 2,000

μž…μΆœλ ₯ μ˜ˆ

3 [10, 100, 20, 150, 1, 100, 200]  [10, 10, 10, 20, 20, 100, 100]
4 [0, 300, 40, 300, 20, 70, 150, 50, 500, 1000] [0, 0, 0, 0, 20, 40, 70, 70, 150, 300]

✏️ 풀이

맀번 정렬을 μˆ˜ν–‰ν•˜λ©΄ μ‹œκ°„μ΄ˆκ³Όκ°€ λ‚  수 μžˆμ„ 것이라고 μƒκ°ν–ˆκΈ° λ•Œλ¬Έμ— logN의 μ‹œκ°„λ³΅μž‘λ„λ₯Ό κ°€μ§€λŠ” μ „ν˜•μ μΈ heap 문제라고 μƒκ°ν–ˆλ‹€. 

 

MinHeap을 μ‚¬μš©ν•΄μ„œ κ°€μž₯ μ•žμ˜ μš”μ†Œλ₯Ό λΊ„ 수 μžˆκ²Œλ”ν•˜κ³ , k만큼의 νž™ 크기λ₯Ό μœ μ§€ν•˜λ©΄μ„œ λ°˜λ³΅λ¬Έμ„ λŒλ Έλ‹€. JSλŠ” heap을 μ§€μ›ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— 직접 κ΅¬ν˜„ν–ˆλ˜ heap 클래슀λ₯Ό μ‚¬μš©ν–ˆλ‹€. μ™ΈλΆ€μ—μ„œ μ‚¬μš©ν•  λ©”μ„œλ“œλ‘œλŠ” get(), show(), size()κ°€ μžˆλŠ”λ° get()은 제일 μž‘μ€ 값을 λΉΌλŠ” μ—­ν• , show()λŠ” 제일 μž‘μ€ 값을 μ‘°νšŒν•˜λŠ” μ—­ν• , size()λŠ” heap μ•ˆμ— μžˆλŠ” μš”μ†Œμ˜ 개수λ₯Ό λ°˜ν™˜ν•˜λŠ” 역할을 ν•œλ‹€. 

 

score 배열을 μˆœνšŒν•˜λ©΄μ„œ 값을 heap에 넣어쀬닀. μ΄λ•Œ k개의 개수λ₯Ό μœ μ§€ν•˜κΈ° μœ„ν•΄μ„œ size()λ₯Ό 톡해 heap λ‚΄ μš”μ†Œμ˜ 개수λ₯Ό λ°˜ν™˜λ°›μ•„ k와 λΉ„κ΅ν–ˆλ‹€. λ§Œμ•½ k보닀 크닀면 get()을 μ΄μš©ν•΄μ„œ μš”μ†Œλ₯Ό 빼쀬닀. λ§ˆμ§€λ§‰μœΌλ‘œλŠ” show()을 μ΄μš©ν•΄μ„œ κ°€μž₯ μž‘μ€ 값을 answer에 넣어쀬닀.

⌨️ μ½”λ“œ

class MinHeap {
  constructor() {
    this.heap = [];
    this.heap.push(-1e9);
  }

  insert(value) {
    this.heap.push(value);
    this.upheap(this.heap.length - 1);
  }

  upheap(pos) {
    let temp = this.heap[pos];

    while (temp < this.heap[parseInt(pos / 2)]) {
      this.heap[pos] = this.heap[parseInt(pos / 2)];
      pos = parseInt(pos / 2);
    }
    this.heap[pos] = temp;
  }

  get() {
    if (this.size() === 0) return 0;
    if (this.size() === 1) return this.heap.pop();
    const result = this.heap[1];
    this.heap[1] = this.heap.pop();
    this.downheap(1, this.heap.length - 1);
    return result;
  }

  downheap(pos, len) {
    let temp = this.heap[pos],
      child;
    while (pos <= parseInt(len / 2)) {
      child = pos * 2;
      if (child < len && this.heap[child] > this.heap[child + 1]) child++;
      if (temp <= this.heap[child]) break;
      this.heap[pos] = this.heap[child];
      pos = child;
    }
    this.heap[pos] = temp;
  }

  show() {
    return this.heap[1];
  }

  size() {
    return this.heap.length - 1;
  }
}

function solution(k, score) {
  var answer = [];

  const hallOfFame = new MinHeap();

  for (const s of score) {
    hallOfFame.insert(s);
    if (hallOfFame.size() > k) hallOfFame.get();

    answer.push(hallOfFame.show());
  }

  return answer;
}