Smallest Range Covering Elements from K Lists

HardArrayHash TableGreedySliding WindowSortingHeap (Priority Queue)

Solution

Solution1: Heap

import { Heap } from '@algorithm/lib';
 
export function smallestRange(nums: number[][]): number[] {
  const k = nums.length;
  const heap = new Heap<number[]>(sortArr);
 
  let maxValue = Number.MIN_SAFE_INTEGER;
  let [start, end] = [0, Number.MAX_SAFE_INTEGER];
  for (let i = 0; i < k; i++) {
    heap.push([nums[i][0], i, 0]);
    maxValue = Math.max(maxValue, nums[i][0]);
  }
 
  while (heap.length === nums.length) {
    const [minValue, row, col] = heap.pop()!;
    if (maxValue - minValue < end - start) {
      start = minValue;
      end = maxValue;
    }
 
    if (col + 1 < nums[row].length) {
      const nextValue = nums[row][col + 1];
      heap.push([nextValue, row, col + 1]);
      maxValue = Math.max(maxValue, nextValue);
    }
  }
 
  return [start, end];
}
 
function sortArr(a: number[], b: number[]) {
  for (let i = 0; i < Math.min(a.length, b.length); i++) {
    if (a[i] !== b[i]) {
      return a[i] - b[i];
    }
  }
  return 0;
}

Complexity

N: nums의 길이, K: nums의 요소의 길이

  • Time: O(NlogK)
  • Space: O(k)

Solution2: Two Pointer

export function smallestRange(nums: number[][]): number[] {
  const k = nums.length;
  const merged = nums.flatMap((num, col) => num.map((value) => [value, col]));
  merged.sort((a, b) => a[0] - b[0]);
 
  const freq = new Map<number, number>();
  let [left, count] = [0, 0];
  let [start, end] = [0, Number.MAX_SAFE_INTEGER];
 
  for (let right = 0; right < merged.length; right++) {
    const rightCol = merged[right][1];
    freq.set(rightCol, (freq.get(rightCol) ?? 0) + 1);
    if (freq.get(rightCol) === 1) {
      count += 1;
    }
 
    while (count === k) {
      const range = merged[right][0] - merged[left][0];
      if (range < end - start) {
        [start, end] = [merged[left][0], merged[right][0]];
      }
 
      const leftCol = merged[left][1];
      freq.set(leftCol, (freq.get(leftCol) ?? 0) - 1);
      if (freq.get(leftCol) === 0) {
        count -= 1;
      }
      left += 1;
    }
  }
 
  return [start, end];
}

Complexity

  • Time: O(NlogN)
  • Space: O(N)