Skip to content

Commit 6f8e99d

Browse files
authored
Leetcode solution merge interval.java (#375)
1 parent 65615f7 commit 6f8e99d

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed
+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
class Solution {
2+
private Map<int[], List<int[]>> graph;
3+
private Map<Integer, List<int[]>> nodesInComp;
4+
private Set<int[]> visited;
5+
6+
// return whether two intervals overlap (inclusive)
7+
private boolean overlap(int[] a, int[] b) {
8+
return a[0] <= b[1] && b[0] <= a[1];
9+
}
10+
11+
// build a graph where an undirected edge between intervals u and v exists
12+
// iff u and v overlap.
13+
private void buildGraph(int[][] intervals) {
14+
graph = new HashMap<>();
15+
for (int[] interval : intervals) {
16+
graph.put(interval, new LinkedList<>());
17+
}
18+
19+
for (int[] interval1 : intervals) {
20+
for (int[] interval2 : intervals) {
21+
if (overlap(interval1, interval2)) {
22+
graph.get(interval1).add(interval2);
23+
graph.get(interval2).add(interval1);
24+
}
25+
}
26+
}
27+
}
28+
29+
// merges all of the nodes in this connected component into one interval.
30+
private int[] mergeNodes(List<int[]> nodes) {
31+
int minStart = nodes.get(0)[0];
32+
for (int[] node : nodes) {
33+
minStart = Math.min(minStart, node[0]);
34+
}
35+
36+
int maxEnd = nodes.get(0)[1];
37+
for (int[] node : nodes) {
38+
maxEnd = Math.max(maxEnd, node[1]);
39+
}
40+
41+
return new int[] {minStart, maxEnd};
42+
}
43+
44+
// use depth-first search to mark all nodes in the same connected component
45+
// with the same integer.
46+
private void markComponentDFS(int[] start, int compNumber) {
47+
Stack<int[]> stack = new Stack<>();
48+
stack.add(start);
49+
50+
while (!stack.isEmpty()) {
51+
int[] node = stack.pop();
52+
if (!visited.contains(node)) {
53+
visited.add(node);
54+
55+
if (nodesInComp.get(compNumber) == null) {
56+
nodesInComp.put(compNumber, new LinkedList<>());
57+
}
58+
nodesInComp.get(compNumber).add(node);
59+
60+
for (int[] child : graph.get(node)) {
61+
stack.add(child);
62+
}
63+
}
64+
}
65+
}
66+
67+
// gets the connected components of the interval overlap graph.
68+
private void buildComponents(int[][] intervals) {
69+
nodesInComp = new HashMap<>();
70+
visited = new HashSet<>();
71+
int compNumber = 0;
72+
73+
for (int[] interval : intervals) {
74+
if (!visited.contains(interval)) {
75+
markComponentDFS(interval, compNumber);
76+
compNumber++;
77+
}
78+
}
79+
}
80+
81+
public int[][] merge(int[][] intervals) {
82+
buildGraph(intervals);
83+
buildComponents(intervals);
84+
85+
// for each component, merge all intervals into one interval.
86+
List<int[]> merged = new LinkedList<>();
87+
for (int comp = 0; comp < nodesInComp.size(); comp++) {
88+
merged.add(mergeNodes(nodesInComp.get(comp)));
89+
}
90+
91+
return merged.toArray(new int[merged.size()][]);
92+
}
93+
}

0 commit comments

Comments
 (0)