Merge Overlapping Intervals
Problem
The first line has n. The next n lines have an interval start and end. Merge all intervals that overlap (touching intervals like 1 4 and 4 5 also merge). Print the merged intervals sorted by start, one per line.
Constraints
- 1 <= n <= 10^4
Examples
Input
4 1 3 2 6 8 10 15 18
Output
1 6 8 10 15 18
Solutions
After sorting by start, an interval can only overlap with the last merged interval. So one pass is enough.
/*
* Problem : Merge intervals.
* Input : n, then n lines with start and end.
* Output : The merged intervals.
* Approach: Sort by start.
* Time : O(n log n)
* Space : O(n)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String[] lines) {
int n = Integer.parseInt(lines[0]);
int[][] intervals = new int[n][2];
for (int i = 0; i < n; i++) {
String[] parts = lines[i + 1].split(" ");
intervals[i][0] = Integer.parseInt(parts[0]);
intervals[i][1] = Integer.parseInt(parts[1]);
}
// Step 1: Sort the intervals by their start. Then overlapping intervals stand next to each other.
java.util.Arrays.sort(intervals, (x, y) -> Integer.compare(x[0], y[0]));
java.util.List<int[]> merged = new java.util.ArrayList<>();
for (int[] interval : intervals) {
int[] last = merged.isEmpty() ? null : merged.get(merged.size() - 1);
// Step 2: If the interval starts before the last merged one ends, they overlap. Extend the end.
if (last != null && interval[0] <= last[1]) {
last[1] = Math.max(last[1], interval[1]);
} else {
// Step 3: Otherwise start a new merged interval.
merged.add(new int[] {interval[0], interval[1]});
}
}
String[] output = new String[merged.size()];
for (int i = 0; i < output.length; i++) {
output[i] = merged.get(i)[0] + " " + merged.get(i)[1];
}
return output;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
java.util.List<String> all = new java.util.ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
all.add(line);
}
}
String[] lines = all.toArray(new String[0]);
System.out.println(String.join("\n", solve(lines)));
}
}
Hints (1)
- Why do we sort first?