Algorithm

[Algorithm] μ΄μ€‘μš°μ„ μˆœμœ„ 큐

ghkdu2 2023. 2. 25. 14:27

πŸ“‹ 문제

이쀑 μš°μ„ μˆœμœ„ νλŠ” λ‹€μŒ 연산을 ν•  수 μžˆλŠ” 자료ꡬ쑰λ₯Ό λ§ν•©λ‹ˆλ‹€.

λͺ…λ Ήμ–΄μˆ˜μ‹  탑(높이)
I 숫자 큐에 μ£Όμ–΄μ§„ 숫자λ₯Ό μ‚½μž…ν•©λ‹ˆλ‹€.
D 1 νμ—μ„œ μ΅œλŒ“κ°’μ„ μ‚­μ œν•©λ‹ˆλ‹€.
D -1 νμ—μ„œ μ΅œμ†Ÿκ°’μ„ μ‚­μ œν•©λ‹ˆλ‹€.

이쀑 μš°μ„ μˆœμœ„ 큐가 ν•  μ—°μ‚° operationsκ°€ λ§€κ°œλ³€μˆ˜λ‘œ μ£Όμ–΄μ§ˆ λ•Œ, λͺ¨λ“  연산을 μ²˜λ¦¬ν•œ ν›„ 큐가 λΉ„μ–΄μžˆμœΌλ©΄ [0,0] λΉ„μ–΄μžˆμ§€ μ•ŠμœΌλ©΄ [μ΅œλŒ“κ°’, μ΅œμ†Ÿκ°’]을 return ν•˜λ„λ‘ solution ν•¨μˆ˜λ₯Ό κ΅¬ν˜„ν•΄μ£Όμ„Έμš”.

 

μ œν•œ 사항

  • operationsλŠ” 길이가 1 이상 1,000,000 μ΄ν•˜μΈ λ¬Έμžμ—΄ λ°°μ—΄μž…λ‹ˆλ‹€.
  • operations의 μ›μ†ŒλŠ” 큐가 μˆ˜ν–‰ν•  연산을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
    • μ›μ†ŒλŠ” “λͺ…λ Ήμ–΄ 데이터” ν˜•μ‹μœΌλ‘œ μ£Όμ–΄μ§‘λ‹ˆλ‹€.- μ΅œλŒ“κ°’/μ΅œμ†Ÿκ°’μ„ μ‚­μ œν•˜λŠ” μ—°μ‚°μ—μ„œ μ΅œλŒ“κ°’/μ΅œμ†Ÿκ°’μ΄ λ‘˜ 이상인 경우, ν•˜λ‚˜λ§Œ μ‚­μ œν•©λ‹ˆλ‹€.
  • 빈 큐에 데이터λ₯Ό μ‚­μ œν•˜λΌλŠ” 연산이 μ£Όμ–΄μ§ˆ 경우, ν•΄λ‹Ή 연산은 λ¬΄μ‹œν•©λ‹ˆλ‹€.

 

μž…μΆœλ ₯ 예

["I 16", "I -5643", "D -1", "D 1", "D 1", "I 123", "D -1"] [0,0]
["I -45", "I 653", "D 1", "I -642", "I 45", "I 97", "D 1", "D -1", "I 333"] [333, -45]

 

 

✏️ 풀이

λ°°μ—΄(operations)의 길이가 1,000,000 μ΄ν•˜μ΄κΈ° λ•Œλ¬Έμ— λ‹Ήμ—°νžˆ 맀번 정렬을 μ‹œμΌœμ£ΌλŠ” 것은 νš¨μœ¨μ„± μΈ‘λ©΄μ—μ„œ ν†΅κ³Όλ˜μ§€ μ•Šμ„ 것이라고 μƒκ°ν–ˆλ‹€. 이후 νž™μ„ μ‚¬μš©ν•΄μ„œ ν•˜λŠ” 방법을 μ‹œλ„ν•˜λ €κ³  κ³ λ―Όν–ˆλŠ”λ° μ΅œμ†Œκ°’, μ΅œλŒ€κ°’ 두 κ°€μ§€λ₯Ό κ³ λ €ν•΄μ•Ό ν–ˆκΈ° λ•Œλ¬Έμ— max heapκ³Ό min heap을 λ‘˜ λ‹€ μ‚¬μš©ν•΄μ•Όκ² λ‹€κ³  μƒκ°ν•˜κ³  문제λ₯Ό ν’€κΈ° μ‹œμž‘ν–ˆλ‹€.

 

"I" λͺ…λ Ήμ–΄κ°€ μž…λ ₯되면 두 κ°€μ§€ νž™μ— 값을 λ„£μ–΄μ€€λ‹€. "D" λͺ…λ Ήμ–΄κ°€ μž…λ ₯되면 μ΅œλŒ€κ°’μ„ λΉΌλŠ” 1의 경우 max heapμ—μ„œ μ΅œλŒ€κ°’μ„ λΉΌμ£Όκ³  λ°˜λŒ€μΈ κ²½μš°μ—λŠ” min heapμ—μ„œ μ΅œμ†Œκ°’μ„ 빼쀬닀. μΆ”κ°€μ μœΌλ‘œ cntλΌλŠ” λ³€μˆ˜λ₯Ό ν†΅ν•΄μ„œ ν˜„μž¬ 큐에 μžˆλŠ” 숫자 개수λ₯Ό μΉ΄μš΄νŒ… ν•΄μ€¬λŠ”λ° 넣어쀄 λ•ŒλŠ” λ‘˜λ‹€ λ„£μ–΄μ£Όμ§€λ§Œ λΊ„λ•ŒλŠ” 각각의 νž™μ—μ„œ λΉΌκΈ° λ•Œλ¬Έμ— 갯수 차이가 λ‚˜κΈ° λ•Œλ¬Έμ΄λ‹€. for문을 돌고 answerλ₯Ό λ°˜ν™˜ν•˜κΈ° 전에 answer에 각각 νž™μ—μ„œ λΊ€ 값을 λ„£μ–΄μ£ΌλŠ”λ° μ΄λ•Œ μ˜λ„μΉ˜ μ•Šμ€ 값이 λ‚˜μ˜¬ 수 μžˆλ‹€. λ§Œμ•½ heap에 "I"λͺ…λ Ήμ–΄κ°€ 10번, "D 1" λͺ…λ Ήμ–΄κ°€ 10번 이루어지면 νμ—λŠ” 값이 μ—†μ–΄ [0, 0]을 λ°˜ν™˜ν•΄μ•Ό ν•˜λŠ”λ° min heapμ—λŠ” 값이 λ‚¨μ•„μžˆκΈ° λ•Œλ¬Έμ— λ‹€λ₯Έ 값을 λ°˜ν™˜ν•˜κ²Œ λœλ‹€. λ”°λΌμ„œ cntκ°€ 0이 λ˜λŠ” κ²½μš°μ— 각 heap을 λΉ„μ›Œμ£ΌκΈ° μœ„ν•¨μ΄λ‹€.

 

 

⌨️ μ½”λ“œ

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;
  }

  clear() {
    this.heap = [-1e9];
  }

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

class MaxHeap {
  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;
  }

  clear() {
    this.heap = [1e9];
  }

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

function solution(operations) {
  var answer = [];
  let cnt = 0;

  const maxHeap = new MaxHeap();
  const minHeap = new MinHeap();

  for (const o of operations) {
    const [cmd, n] = o.split(' ');

    if (cmd === 'I') {
      maxHeap.insert(+n);
      minHeap.insert(+n);
      cnt += 1;
    } else {
      if (cnt) {
        if (n === '1') maxHeap.get();
        else minHeap.get();
        cnt -= 1;
      }
      if (!cnt) {
        minHeap.clear();
        maxHeap.clear();
      }
    }
  }

  answer.push(maxHeap.get());
  answer.push(minHeap.get());

  return answer;
}