< Summary

Information
Class: LeetCode.Algorithms.MinimumHeightTrees.MinimumHeightTreesBreadthFirstSearch
Assembly: LeetCode
File(s): D:\a\LeetCode-CS\LeetCode-CS\source\LeetCode\Algorithms\MinimumHeightTrees\MinimumHeightTreesBreadthFirstSearch.cs
Line coverage
100%
Covered lines: 62
Uncovered lines: 0
Coverable lines: 62
Total lines: 112
Line coverage: 100%
Branch coverage
100%
Covered branches: 18
Total branches: 18
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
FindMinHeightTrees(...)100%22100%
GetNodesDictionary(...)100%66100%
GetMaxNodeDepth(...)100%1010100%

File(s)

D:\a\LeetCode-CS\LeetCode-CS\source\LeetCode\Algorithms\MinimumHeightTrees\MinimumHeightTreesBreadthFirstSearch.cs

#LineLine coverage
 1// --------------------------------------------------------------------------------
 2// Copyright (C) 2025 Eugene Eremeev (also known as Yevhenii Yeriemeieiv).
 3// All Rights Reserved.
 4// --------------------------------------------------------------------------------
 5// This software is the confidential and proprietary information of Eugene Eremeev
 6// (also known as Yevhenii Yeriemeieiv) ("Confidential Information"). You shall not
 7// disclose such Confidential Information and shall use it only in accordance with
 8// the terms of the license agreement you entered into with Eugene Eremeev (also
 9// known as Yevhenii Yeriemeieiv).
 10// --------------------------------------------------------------------------------
 11
 12namespace LeetCode.Algorithms.MinimumHeightTrees;
 13
 14/// <inheritdoc />
 15public class MinimumHeightTreesBreadthFirstSearch : IMinimumHeightTrees
 16{
 17    /// <summary>
 18    ///     Time complexity - O(V * (V + E)), where V is the number of vertices(nodes) and E is the number of edges.
 19    ///     Space complexity - O(V + E), where V is the number of vertices(nodes) and E is the number of edges.
 20    /// </summary>
 21    /// <param name="n"></param>
 22    /// <param name="edges"></param>
 23    /// <returns></returns>
 24    public IList<int> FindMinHeightTrees(int n, int[][] edges)
 1025    {
 1026        if (n == 1)
 127        {
 128            return new List<int> { 0 };
 29        }
 30
 931        var nodesDictionary = GetNodesDictionary(edges);
 32
 933        var maxNodeDepths = GetMaxNodeDepth(nodesDictionary);
 34
 5935        var minDepth = maxNodeDepths.Select(v => v.maxDepth).Min();
 36
 7437        return maxNodeDepths.Where(v => v.maxDepth.Equals(minDepth)).Select(v => v.node).ToList();
 1038    }
 39
 40    private static Dictionary<int, List<int>> GetNodesDictionary(IEnumerable<int[]> edges)
 941    {
 942        var nodesDictionary = new Dictionary<int, List<int>>();
 43
 10944        foreach (var edge in edges)
 4145        {
 4146            var root = edge[0];
 4147            var leaf = edge[1];
 48
 4149            if (nodesDictionary.TryGetValue(root, out var rootValue))
 3150            {
 3151                rootValue.Add(leaf);
 3152            }
 53            else
 1054            {
 1055                nodesDictionary.Add(root, [leaf]);
 1056            }
 57
 4158            if (nodesDictionary.TryGetValue(leaf, out var leafValue))
 159            {
 160                leafValue.Add(root);
 161            }
 62            else
 4063            {
 4064                nodesDictionary.Add(leaf, [root]);
 4065            }
 4166        }
 67
 968        return nodesDictionary;
 969    }
 70
 71    private static List<(int node, int maxDepth)> GetMaxNodeDepth(Dictionary<int, List<int>> nodesDictionary)
 972    {
 973        var maxNodeDepths = new List<(int node, int maxDepth)>();
 74
 12775        foreach (var node in nodesDictionary)
 5076        {
 5077            var maxNodeDepth = 0;
 78
 5079            var nodesQueue = new Queue<(int, int)>();
 80
 5081            var visitedNodes = new HashSet<int> { node.Key };
 82
 31483            foreach (var value in node.Value)
 8284            {
 8285                nodesQueue.Enqueue((value, 1));
 8286            }
 87
 32088            while (nodesQueue.Count > 0)
 27089            {
 27090                var (currentNode, currentNodeDepth) = nodesQueue.Dequeue();
 91
 27092                visitedNodes.Add(currentNode);
 93
 172694                foreach (var edgesDictionaryItemCur in nodesDictionary[currentNode])
 45895                {
 45896                    if (visitedNodes.Contains(edgesDictionaryItemCur))
 27097                    {
 27098                        maxNodeDepth = Math.Max(maxNodeDepth, currentNodeDepth);
 27099                    }
 100                    else
 188101                    {
 188102                        nodesQueue.Enqueue((edgesDictionaryItemCur, currentNodeDepth + 1));
 188103                    }
 458104                }
 270105            }
 106
 50107            maxNodeDepths.Add((node.Key, maxNodeDepth));
 50108        }
 109
 9110        return maxNodeDepths;
 9111    }
 112}