Skip to content

3439. Find Minimum Diameter After Merging Two Trees

Difficulty: Hard

LeetCode Problem View on GitHub


3439. Find Minimum Diameter After Merging Two Trees

Hard


There exist two undirected trees with n and m nodes, numbered from 0 to n - 1 and from 0 to m - 1, respectively. You are given two 2D integer arrays edges1 and edges2 of lengths n - 1 and m - 1, respectively, where edges1[i] = [ai, bi] indicates that there is an edge between nodes ai and bi in the first tree and edges2[i] = [ui, vi] indicates that there is an edge between nodes ui and vi in the second tree.

You must connect one node from the first tree with another node from the second tree with an edge.

Return the minimum possible diameter of the resulting tree.

The diameter of a tree is the length of the longest path between any two nodes in the tree.

 

Example 1:

Input: edges1 = [[0,1],[0,2],[0,3]], edges2 = [[0,1]]

Output: 3

Explanation:

We can obtain a tree of diameter 3 by connecting node 0 from the first tree with any node from the second tree.

Example 2:

Input: edges1 = [[0,1],[0,2],[0,3],[2,4],[2,5],[3,6],[2,7]], edges2 = [[0,1],[0,2],[0,3],[2,4],[2,5],[3,6],[2,7]]

Output: 5

Explanation:

We can obtain a tree of diameter 5 by connecting node 0 from the first tree with node 0 from the second tree.

 

Constraints:

  • 1 <= n, m <= 105
  • edges1.length == n - 1
  • edges2.length == m - 1
  • edges1[i].length == edges2[i].length == 2
  • edges1[i] = [ai, bi]
  • 0 <= ai, bi < n
  • edges2[i] = [ui, vi]
  • 0 <= ui, vi < m
  • The input is generated such that edges1 and edges2 represent valid trees.

Solution

class Solution {
public:
    //why the same solution in java is giving tle; ????
    int minimumDiameterAfterMerge(vector<vector<int>>& edges1, vector<vector<int>>& edges2) {
        vector<vector<int>> adj1(100007);
        vector<vector<int>> adj2(100007);
        for (auto& edge : edges1) {
            int u = edge[0], v = edge[1];
            adj1[u].push_back(v);
            adj1[v].push_back(u);
        }
        for (auto& edge : edges2) {
            int u = edge[0], v = edge[1];
            adj2[u].push_back(v);
            adj2[v].push_back(u);
        }
        if (edges1.empty() && edges2.empty()) return 1;
        if (edges1.empty()) {
            int d2 = findDiameter(adj2, edges2.size() + 1);
            if (edges2.size() == 1) return d2 + 1;
            else return d2;
        }
        if (edges2.empty()) {
            int d1 = findDiameter(adj1, edges1.size() + 1);
            if (edges1.size() == 1) return d1 + 1;
            else return d1;
        }
        int d1 = findDiameter(adj1, edges1.size() + 1);
        int d2 = findDiameter(adj2, edges2.size() + 1);
        int res = (d1 / 2) + (d2 / 2) + 1;
        if (d1 % 2 == 1) res++;
        if (d2 % 2 == 1) res++;
        res = max(res, d1);
        res = max(res, d2);
        return res;
    }
    int findDiameter(vector<vector<int>>& adj, int len) {
        int n = len;
        vector<int> depth(n + 1, 0);
        dfs(0, -1, adj, depth);
        int maxi = 0, node = -1;
        for (int i = 0; i <= n; ++i) {
            if (depth[i] > maxi) {
                maxi = depth[i];
                node = i;
            }
        }
        fill(depth.begin(), depth.end(), 0);
        dfs(node, -1, adj, depth);
        maxi = 0; node = - 1;
        for (int i = 0; i <= n; ++i) {
            if (depth[i] > maxi) {
                maxi = depth[i];
                node = i;
            }
        }
        return maxi;
    }
    void dfs(int u, int par, vector<vector<int>>& adj, vector<int>& depth) {
        for (int v : adj[u]) {
            if (v != par) {
                depth[v] = 1 + depth[u];
                dfs(v, u, adj, depth);
            }
        }
    }
};

Complexity Analysis

  • Time Complexity: O(?)
  • Space Complexity: O(?)

Approach

Detailed explanation of the approach will be added here