Sort and merge overlapping intervals, insert into sorted lists, and solve meeting room problems.
Published March 23, 2025
Interval problems involve ranges [start, end]. The canonical approach: sort by start time, then process overlaps linearly.
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]); // sort by start
List<int[]> merged = new ArrayList<>();
merged.add(intervals[0]);
for (int i = 1; i < intervals.length; i++) {
int[] last = merged.get(merged.size() - 1);
int[] curr = intervals[i];
if (curr[0] <= last[1]) {
// Overlap: extend the last interval
last[1] = Math.max(last[1], curr[1]);
} else {
merged.add(curr);
}
}
return merged.toArray(new int[0][]);
}
public int[][] insert(int[][] intervals, int[] newInterval) {
List<int[]> result = new ArrayList<>();
int i = 0, n = intervals.length;
// Add all intervals ending before newInterval starts
while (i < n && intervals[i][1] < newInterval[0])
result.add(intervals[i++]);
// Merge overlapping intervals
while (i < n && intervals[i][0] <= newInterval[1]) {
newInterval[0] = Math.min(newInterval[0], intervals[i][0]);
newInterval[1] = Math.max(newInterval[1], intervals[i][1]);
i++;
}
result.add(newInterval);
// Add remaining intervals
while (i < n) result.add(intervals[i++]);
return result.toArray(new int[0][]);
}
public boolean canAttendMeetings(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
for (int i = 1; i < intervals.length; i++)
if (intervals[i][0] < intervals[i-1][1]) return false;
return true;
}
// Greedy with min-heap: track end times of ongoing meetings
public int minMeetingRooms(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
PriorityQueue<Integer> endTimes = new PriorityQueue<>(); // min-heap
for (int[] interval : intervals) {
if (!endTimes.isEmpty() && endTimes.peek() <= interval[0])
endTimes.poll(); // reuse room (meeting ended)
endTimes.offer(interval[1]);
}
return endTimes.size(); // rooms in use = distinct overlapping meetings
}
public int eraseOverlapIntervals(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[1] - b[1]); // sort by END time
int count = 0, end = Integer.MIN_VALUE;
for (int[] interval : intervals) {
if (interval[0] >= end) {
end = interval[1]; // keep this interval
} else {
count++; // remove this overlapping interval
}
}
return count;
}
// Two intervals [a,b] and [c,d] overlap if: a <= d && c <= b
public boolean overlaps(int a, int b, int c, int d) {
return a <= d && c <= b;
}
max(start1, start2) < min(end1, end2).