diff --git a/java/find-minimum-diameter-after-merging-two-trees.java b/java/find-minimum-diameter-after-merging-two-trees.java new file mode 100644 index 0000000..60da42e --- /dev/null +++ b/java/find-minimum-diameter-after-merging-two-trees.java @@ -0,0 +1,65 @@ +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; + +class Solution { + private List> makeGraph(int[][] edges) { + var n = edges.length + 1; + + var g = new ArrayList>(); + for (int i = 0; i < n; ++i) { + g.add(new ArrayList<>()); + } + + for (var edge : edges) { + g.get(edge[0]).add(edge[1]); + g.get(edge[1]).add(edge[0]); + } + + return g; + } + + private int getDiameter(int[][] edges) { + var n = edges.length + 1; + var g = makeGraph(edges); + var deg = new int[n]; + + var q = new ArrayDeque(); + for (int i = 0; i < n; ++i) { + deg[i] = g.get(i).size(); + if (deg[i] == 1) { + q.offer(i); + } + } + + int levelsRemoved = 0; + + int remaining = n; + while (remaining > 2) { + var size = q.size(); + remaining -= size; + ++levelsRemoved; + + for (int i = 0; i < size; ++i) { + var u = q.poll(); + + for (var v : g.get(u)) { + --deg[v]; + if (deg[v] == 1) { + q.offer(v); + } + } + } + } + + return 2 * levelsRemoved + ((remaining == 2) ? 1 : 0); + } + + public int minimumDiameterAfterMerge(int[][] edges1, int[][] edges2) { + var d1 = getDiameter(edges1); + var d2 = getDiameter(edges2); + var combined = (d1 / 2 + d1 % 2) + (d2 / 2 + d2 % 2) + 1; + + return Math.max(combined, Math.max(d1, d2)); + } +}