Объединить интервалы

Дана коллекция интервалов на горизонтальной линии. Нужно объединить пересекающиеся и вернуть коллекцию непересекающихся интервалов.
Пример 1:
Дано: [[1,3],[2,6],[8,10],[15,18]]
Решение: [[1,6],[8,10],[15,18]]
Объяснение: Поскольку интервалы [1,3] и [2,6] пересекатся, мы их объединяем в один [1,6].
Пример 2:
Дано: [[1,4],[4,5]]
Решение: [[1,5]]
Объяснение: Интервалы [1,4] и [4,5] пересекаются в точке 4.
Идея решения
Отсортируем наши интервалы по их стартовой точке. И добавим первый интервал в список merged, который выдадим, как результат. Далее смотрим на следующий интервал. Если его начальная точка больше, чем конечная точка последнего интервала в нашем списке, то это непересекающиеся интрвалы, и мы опять добавляем текущий интервал в список, и будем его сравнивать со следущим. Если же начальная точка следующего интрвала МЕНЬШЕ финальной точки последнего интервала из списка merged, то они пересекаются, мы обновляем последний интервал в списке, ничего нового не добавляем.
Компилируемое решение
class Solution {
// функция сортировки инетрвалов по первой точке
  private class IntervalComparator implements Comparator<int[]> {
    @Override
    public int compare(int[] a, int[] b) {
      return a[0] < b[0] ? -1 : a[0] == b[0] ? 0 : 1;
    }
  }

  public int[][] merge(int[][] intervals) {
    Collections.sort(Arrays.asList(intervals), new IntervalComparator());

    LinkedList<int[]> merged = new LinkedList<>();
    for (int[] interval : intervals) {
      // текущий интервал добавляется к списку, если список пуст
     // или его последний интервал не пересекается с текущим
      if (merged.isEmpty() || merged.getLast()[1] < interval[0]) {
        merged.add(interval);
      }
      // если они пересекаются, то последний интервал из списка объединяется с текущим
      // путем обновления финальной точки последнего интервала, которая принимает значение
      // финальной точки текущего интервала,
      // если она больше финальной точки последнего интервала
      else {
        merged.getLast()[1] = Math.max(merged.getLast()[1], interval[1]);
      }
    }

    return merged.toArray(new int[merged.size()][]);
  }
}

Комментарии

Популярные сообщения из этого блога

Разбиение числа на сумму с максимальным произведнием слагаемых

Число подмассивов, в которых сумма элементов равна k

Сложить два числа, которые представлены списком