Divide Intervals Into Minimum Number of Groups

MediumArrayTwo PointersGreedySortingHeap (Priority Queue)Prefix Sum

Solution

Solution1: Sort

export function minGroups(intervals: number[][]): number {
  const events: number[][] = [];
  for (const [start, end] of intervals) {
    events.push([start, 1]);
    events.push([end + 1, -1]);
  }
  events.sort((a, b) => (a[0] !== b[0] ? a[0] - b[0] : a[1] - b[1]));
 
  let concurrentIntervals = 0;
  let maxConcurrentIntervals = 0;
  for (const event of events) {
    concurrentIntervals += event[1];
    maxConcurrentIntervals = Math.max(maxConcurrentIntervals, concurrentIntervals);
  }
  return maxConcurrentIntervals;
}

Complexity

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

Solution2: Line Sweep

export function minGroups(intervals: number[][]): number {
  let [minStart, maxEnd] = [Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER];
  for (const [start, end] of intervals) {
    minStart = Math.min(minStart, start);
    maxEnd = Math.max(maxEnd, end);
  }
 
  const points = new Array<number>(maxEnd + 2).fill(0);
  for (const [start, end] of intervals) {
    points[start] += 1;
    points[end + 1] -= 1;
  }
 
  let concurrentIntervals = 0;
  let maxConcurrentIntervals = 0;
  for (let i = minStart; i <= maxEnd; i++) {
    concurrentIntervals += points[i];
    maxConcurrentIntervals = Math.max(maxConcurrentIntervals, concurrentIntervals);
  }
  return maxConcurrentIntervals;
}

Complexity

N: intervals의 길이, K: intervals의 값의 범위

  • Time: O(N+K)
  • Space: O(K)