const rearrangeBarcodes = (arr) => {
  const ans = [];
  // arr to hashmap
  const hash = {};
  arr.forEach((item) => {
    hash[item] = hash[item] ? ++hash[item] : 1;
  });
  // helper
  const swap = (arr, idx1, idx2) => {
    const temp = arr[idx1];
    arr[idx1] = arr[idx2];
    arr[idx2] = temp;
  };
  // hash to pq, heapify up
  const pq = [null];
  Object.entries(hash).forEach((item) => {
    const [value, freq] = item;
    pq.push({ value, freq });
    let childIdx = pq.length - 1;
    while (childIdx > 1) {
      let parentIdx = Math.floor(childIdx / 2);
      if (pq[parentIdx].freq < freq) {
        swap(pq, parentIdx, childIdx);
      }
      childIdx = parentIdx;
    }
  });
  const poll = (value) => {
    let idx = 1;
    if (pq[idx].value === value) {
      const left = pq[2];
      const right = pq[3];
      if (pq[2].freq !== 0) {
        idx = 2;
        if (right && right.freq !== 0) {
          idx = pq[2] > pq[3] ? 2 : 3;
        }
      }
    }
    let head = pq[idx];
    ans.push(head.value);
    head.freq--;
    while (idx * 2 < pq.length) {
      // heapify down
      const leftIdx = idx * 2;
      const rightIdx = idx * 2 + 1;
      let childMaxIdx = leftIdx;
      if (rightIdx < pq.length) {
        childMaxIdx = pq[leftIdx].freq > pq[rightIdx].freq ? leftIdx : rightIdx;
      }
      if (pq[idx].freq < pq[childMaxIdx].freq) {
        swap(pq, idx, childMaxIdx);
        if (idx === 0) {
          head = pq[idx];
        }
      }
      idx = childMaxIdx;
    }
    return head.value;
  };
  let recent = poll();
  while (pq[1].freq) {
    const last = poll(recent);
    recent = last;
  }
  return ans;
};Level
LeetCode Medium
Recruitment