Объединить интервалы
Дана коллекция интервалов на горизонтальной линии. Нужно объединить пересекающиеся и вернуть коллекцию непересекающихся интервалов.
Пример 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()][]);
}
}
// функция сортировки инетрвалов по первой точке
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()][]);
}
}
Комментарии
Отправить комментарий