Algobase
  • Introduction
  • Leetcode
    • 226. Invert Binary Tree
    • 136. Single Number
    • 104. Maximum Depth of Binary Tree
    • 344. Reverse String
    • 461. Hamming Distance
    • 617. Merge Two Binary Trees
    • 237. Delete Node in a Linked List
    • 412. Fizz Buzz
    • 206. Reverse Linked List
    • 169. Majority Element
    • 108. Convert Sorted Array to Binary Search Tree
    • 283. Move Zeroes
    • 122. Best Time to Buy and Sell Stock II
    • 242. Valid Anagram
    • 171. Excel Sheet Column Number
    • 217. Contains Duplicate
    • 448. Find All Numbers Disappeared in an Array
    • 13. Roman to Integer
    • 21. Merge Two Sorted Lists
    • 100. Same Tree
    • 121. Best Time to Buy and Sell Stock
    • 350. Intersection of Two Arrays II
    • 268. Missing Number
    • 118. Pascal's Triangle
    • 387. First Unique Character in a String
    • 38. Count and Say
    • 26. Remove Duplicates from Sorted Array
    • 1. Two Sum
    • 53. Maximum Subarray
    • 101. Symmetric Tree
    • 70. Climbing Stairs
    • 543. Diameter of Binary Tree
    • 9. Palindrome Number
    • 191. Number of 1 Bits
    • 202. Happy Number
    • 326. Power of Three
    • 198. House Robber
    • 66. Plus One
    • 724. Find Pivot Index
    • 155. Min Stack
    • 14. Longest Common Prefix
    • 278. First Bad Version
    • 125. Valid Palindrome
    • 172. Factorial Trailing Zeros
    • 20. Valid Parentheses
    • 234. Palindrome Linked List
    • 88. Merge Sorted Array
    • 190. Reverse Bits
    • 160. Intersection of Two Linked Lists
    • 141. Linked List Cycle
    • 189. Rotate Array
    • 28. Implement strStr()
    • 69. Sqrt(x)
    • 204. Count Primes
    • 581. Shortest Unsorted Continuous Subarray
    • 7. Reverse Integer
    • 763. Partition Labels
    • 338. Counting Bits
    • 406. Queue Reconstruction by Height
    • 46. Permutations
    • 94. Binary Tree Inorder Traversal
    • 739. Daily Temperature
    • 22. Generate Parentheses
    • 78. Subsets
    • 347. Top K Frequent Elements
    • 647. Palindromic Substrings
    • 230. Kth Smallest Element in a BST
    • 238. Product of Array Except Self
    • 1143. Longest Common Subsequence
    • 48. Rotate Image
    • 49. Group Anagrams
    • 39. Combination Sum
    • 454. 4Sum II
    • 62. Unique Paths
    • 378. Kth Smallest Element in a Sorted Matrix
    • 64. Minimum Path Sum
    • 102. Binary Tree Level Order Traversal
    • 289. Game of Life
    • 145. Binary Tree Postorder Traversal
    • 287. Find the Duplicate Number
    • 215. Kth Largest Element in an Array
    • 328. Odd Even Linked List
    • 875. Koko Eating Bananas
    • 384. Shuffle an Array
    • 341. Flatten Nested List Iterator
    • 96. Unique Binary Search Trees
    • 11. Container With Most Water
    • 337. House Robber III
    • 394. Decode String
    • 371. Sum of Two Integers
    • 621. Task Scheduler
    • 208. Implement Trie (Prefix Tree)
    • 114. Flatten Binary Tree to Linked List
    • 105. Construct Binary Tree from Preorder and Inorder Traversal
    • 75. Sort Colors
    • 131. Palindrome Partitioning
    • 103. Binary Tree Zigzag Level Order Traversal
    • 36. Valid Sudoku
    • 17. Letter Combinations of a Phone Number
    • 309. Best Time to Buy and Sell Stock with Cooldown
    • 279. Perfect Squares
    • 380. Insert Delete GetRandom O(1)
    • 116. Populating Next Right Pointers in Each Node
    • 236. Lowest Common Ancestor of a Binary Tree
    • 200. Number of Islands
    • 437. Path Sum III
    • 416. Partition Equal Subset Sum
    • 1049. Last Stone Weight II
    • 494. Target Sum
    • 16. 3Sum Closest
    • 148. Sort List
    • 207. Course Schedule
    • 560. Subarray Sum Equals K
    • 438. Find All Anagrams in a String
    • 300. Longest Increasing Subsequence
    • 240. Search a 2D Matrix II
    • 162. Find Peak Element
    • 73. Set Matrix Zeroes
    • 134. Gas Station
    • 139. Word Break
    • 210. Course Schedule II
    • 395. Longest Substring with At Least K Repeating Characters
    • 787. Cheapest Flights Within K Stops
    • 56. Merge Intervals
    • 334. Increasing Triplet Subsequence
    • 713. Subarray Product Less Than K
    • 142. Linked List Cycle II
    • 221. Maximal Square
    • 138. Copy List with Random Pointer
    • 227. Basic Calculator II
    • 6. ZigZag Conversion
    • 150. Evaluate Reverse Polish Notation
    • 34. Find First and Last Position of Element in Sorted Array
    • 322. Coin Change
    • 79. Word Search
    • 19.Remove Nth Node From End of List
    • 33. Search in Rotated Sorted Array
    • 63. Unique Paths II
    • 146. LRU Cache
    • 2. Add Two Numbers
    • 54. Spiral Matrix
    • 55. Jump Game
    • 50. Pow(x, n)
    • 3. Longest Substring Without Repeating Characters
    • 152. Maximum Product Subarray
    • 5. Longest Palindromic Substring
    • 179. Largest Number
    • 324. Wiggle Sort II
    • 127. Word Ladder
    • 91. Decode Ways
    • 15. 3Sum
    • 98. Validate Binary Search Tree
    • 130. Surrounded Regions
    • 8. String to Integer (atoi)
    • 29. Divide Two Integers
    • 166. Fraction to Recurring Decimal
    • 72. Edit Distance
    • 295. Find Median from Data Stream
    • 123. Best Time to Buy and Sell Stock III
    • 829. Consecutive Numbers Sum
    • 31. Next Permutation
    • 173. Binary Search Tree Iterator
    • 92. Reverse Linked List II
    • 95. Unique Binary Search Trees II
    • 24. Swap Nodes in Pairs
    • 209. Minimum Size Subarray Sum
    • 199. Binary Tree Right Side View
    • 120. Triangle
    • 188. Best Time to Buy and Sell Stock IV
    • 442. Find All Duplicates in an Array
    • 222. Count Complete Tree Nodes
    • 47. Permutations II
    • 109. Convert Sorted List to Binary Search Tree
    • 18. 4Sum
    • 153. Find Minimum in Rotated Sorted Array
    • 654. Maximum Binary Tree
    • 695. Max Area of Island
    • 547. Friend Circles
    • 43. Multiply Strings
    • 310. Minimum Height Trees
    • 516. Longest Palindromic Subsequence
    • 241. Different Ways to Add Parentheses
    • 863. All Nodes Distance K in Binary Tree
    • 143. Reorder List
    • 402. Remove K Digits
    • 450. Delete Node in a BST
  • Algorithms & Data Structure
    • Sorting
  • Leetcode SQL
Powered by GitBook
On this page
  • Solution
  • 1. Naive DFS (Timeout)
  • 2. Topological Sort using Hash Set
  • 3. Topological Sort using Queue

Was this helpful?

  1. Leetcode

310. Minimum Height Trees

https://leetcode.com/problems/minimum-height-trees/

Previous43. Multiply StringsNext516. Longest Palindromic Subsequence

Last updated 4 years ago

Was this helpful?

A tree is an undirected graph in which any two vertices are connected by exactly one path. In other words, any connected graph without simple cycles is a tree.

Given a tree of n nodes labelled from 0 to n - 1, and an array of n - 1 edges where edges[i] = [ai, bi] indicates that there is an undirected edge between the two nodes ai and bi in the tree, you can choose any node of the tree as the root. When you select a node x as the root, the result tree has height h. Among all possible rooted trees, those with minimum height (i.e. min(h)) are called minimum height trees (MHTs).

Return a list of all MHTs' root labels. You can return the answer in any order.

The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.

Example 1:

Input: n = 4, edges = [[1,0],[1,2],[1,3]]
Output: [1]
Explanation: As shown, the height of the tree is 1 when the root is the node with label 1 which is the only MHT.

Example 2:

Input: n = 6, edges = [[3,0],[3,1],[3,2],[3,4],[5,4]]
Output: [3,4]

Example 3:

Input: n = 1, edges = []
Output: [0]

Example 4:

Input: n = 2, edges = [[0,1]]
Output: [0,1]

Constraints:

  • 1 <= n <= 2 * 104

  • edges.length == n - 1

  • 0 <= ai, bi < n

  • ai != bi

  • All the pairs (ai, bi) are distinct.

  • The given input is guaranteed to be a tree and there will be no repeated edges.

Solution

1. Naive DFS (Timeout)

class Solution {
public:
    vector<int> findMinHeightTrees(const int n, vector<vector<int>>& edges) {
        vector<vector<int>> adj(n, vector<int>());
        for (const auto &edge: edges) {
            adj[edge[0]].push_back(edge[1]);
            adj[edge[1]].push_back(edge[0]);
        }
        bool visited[n];
        vector<int> depth(n);
        int min_depth = INT_MAX;
        for (int i = 0; i < n; ++i) {
            memset(visited, 0, n);
            depth[i] = getMaxDepth(i, adj, visited);
            if (depth[i] < min_depth) min_depth = depth[i];
        }
        vector<int> nodes;
        for (int i = 0; i < n; ++i) {
            if (depth[i] == min_depth) nodes.push_back(i);
        }
        return nodes;
    }
    int getMaxDepth(int src, vector<vector<int>> &adj, bool *visited) {
        visited[src] = true;
        int max_depth = 0;
        for (const auto e: adj[src]) {
            if (visited[e]) continue;
            visited[e] = true;
            int d = getMaxDepth(e, adj, visited) + 1;
            if (d > max_depth) max_depth = d;
        }
        return max_depth;
    }
};

2. Topological Sort using Hash Set

class Solution {
public:
    vector<int> findMinHeightTrees(const int n, vector<vector<int>>& edges) {
        vector<unordered_set<int>> adj(n, unordered_set<int>());
        vector<int> current, next, remove;
        for (int i = 0; i < n; ++i) current.push_back(i);
        for (const auto &edge: edges) {
            adj[edge[0]].insert(edge[1]);
            adj[edge[1]].insert(edge[0]);
        }
        while (current.size() > 2) {
            for (const auto e: current) {
                if (adj[e].size() > 1) next.push_back(e);
                else remove.push_back(e);
            }
            for (const auto e: remove) {
                int target = *adj[e].begin();
                adj[target].erase(e);
            }
            remove.clear();
            current.swap(next);
            next.clear();
        }
        return current;
    }
};

3. Topological Sort using Queue

class Solution {
public:
    vector<int> findMinHeightTrees(const int n, vector<vector<int>>& edges) {
        vector<vector<int>> adj(n, vector<int>());
        int degree[n];
        memset(degree, 0, n * sizeof(n));
        for (const auto &edge: edges) {
            adj[edge[0]].push_back(edge[1]);
            adj[edge[1]].push_back(edge[0]);
            ++degree[edge[0]];
            ++degree[edge[1]];
        }
        queue<int> q;
        for (int i = 0; i < n; ++i) {
            if (degree[i] > 1) continue;
            q.push(i);
        }
        
        int left = n;
        while (left > 2) {
            left -= q.size();
            const int sz = q.size();
            for (int i = 0; i < sz; ++i) {
                const int e = q.front();
                q.pop();
                vector<int> &neighbor = adj[e];
                for (const auto _n: neighbor) {
                    --degree[_n];
                    if (degree[_n] == 1) q.push(_n);
                }
            }
        }
        vector<int> centers;
        centers.reserve(q.size());
        while (!q.empty()) {
            centers.push_back(q.front());
            q.pop();
        }
        return centers;
    }
};
  • #tree

  • #dfs

  • #graph

  • #queue

  • #veryimportant