310. Minimum Height Trees

package LeetCode_310

import java.util.*
import kotlin.collections.ArrayList

/**
 * 310. Minimum Height Trees
 * https://leetcode.com/problems/minimum-height-trees/description/
 *
 * For an undirected graph with tree characteristics, we can choose any node as the root.
 * The result graph is then a rooted tree.
 * Among all possible rooted trees, those with minimum height are called minimum height trees (MHTs).
 * Given such a graph, write a function to find all the MHTs and return a list of their root labels.
Format
The graph contains n nodes which are labeled from 0 to n - 1.
You will be given the number n and a list of undirected edges (each edge is a pair of labels).
You can assume that no duplicate edges will appear in edges.
Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.

Example 1 :
Input: n = 4, edges = [[1, 0], [1, 2], [1, 3]]
   0
   |
   1
  / 
 2   3
Output: [1]

 * 说明:
1. 根据树的定义,树是一个无向图,其中任何两个顶点只通过一条路径连接。 换句话说,一个任何没有简单环路的连通图都是一棵树。
2. 树的高度是指根节点和叶子节点之间最长向下路径上边的数量。
 * */
class Solution {
    /*
    * solution:BFS, reduce the in-degree of each node,Time complexity:O(V+E), Space complexity:O(V+E)
    * */
    fun findMinHeightTrees(n_: Int, edges: Array<IntArray>): List<Int> {
        val n = n_
        var result = ArrayList<Int>()
        if (n == 0) {
            return result
        }
        if (n == 1) {
            result.add(0)
            return result
        }

        val indegree = IntArray(n)
        //init and create graph
        val graph = ArrayList<ArrayList<Int>>()
        for (i in 0 until n) {
            graph.add(ArrayList())
        }
        for (edge in edges) {
            graph.get(edge[0]).add(edge[1])
            graph.get(edge[1]).add(edge[0])
            indegree[edge[0]]++
            indegree[edge[1]]++
        }

        val queue = LinkedList<Int>()
        for (i in 0 until n) {
            if (indegree[i]==0){
                return result
            } else if (indegree[i]==1){
                //add leaf node into queue
                queue.offer(i)
            }
        }

        while (queue.isNotEmpty()) {
            result = ArrayList()
            val size = queue.size
            for (i in 0 until size) {
                val cur = queue.poll()
                //result is one or two remaining node
                result.add(cur)
                indegree[cur]--
                //find out leaf node's connect node
                for (k in graph[cur].indices) {
                    val next = graph.get(cur).get(k)
                    if (indegree[next]==0){
                        continue
                    }
                    if (indegree[next]==2) {
                        queue.offer(next)
                    }
                    indegree[next]--
                }
            }
        }

        return result
    }
}
原文地址:https://www.cnblogs.com/johnnyzhao/p/13549246.html