LeetCode 310. Minimum Height Trees

简介: 对于一个具有树特征的无向图,我们可选择任何一个节点作为根。图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树。给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们的根节点。

v2-2a157727e718dbe19119a596953518b8_1440w.jpg

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]


Example 2 :


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


Note:

  • According to the definition of tree on Wikipedia: “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.”
  • The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.


描述



对于一个具有树特征的无向图,我们可选择任何一个节点作为根。图因此可以成为树,在所有可能的树中,具有最小高度的树被称为最小高度树。给出这样的一个图,写出一个函数找到所有的最小高度树并返回他们的根节点。


注意:


该图包含 n 个节点,标记为 0 到 n - 1。给定数字 n 和一个无向边 edges 列表(每一个边都是一对标签)。


你可以假设没有重复的边会出现在 edges 中。由于所有的边都是无向边, [0, 1]和 [1, 0] 是相同的,因此不会同时出现在 edges 里。


示例 1:


输入: n = 4, edges = [[1, 0], [1, 2], [1, 3]]
        0
        |
        1
       / \
      2   3 
输出: [1]


示例 2:


输入: n = 6, edges = [[0, 3], [1, 3], [2, 3], [4, 3], [5, 4]]
     0  1  2
      \ | /
        3
        |
        4
        |
        5 
输出: [3, 4]


说明:

  • 根据树的定义,树是一个无向图,其中任何两个顶点只通过一条路径连接。 换句话说,一个任何没有简单环路的连通图都是一棵树。
  • 树的高度是指根节点和叶子节点之间最长向下路径上边的数量。


思路



  • 最小高度树的根节点是图中最长路径的中间节点.
  • 我们用一个 List[set()] 的结构存储每个节点可以访问到的其他节点。一般情况下应该使用字典,以节点为键,能够遍历到的节点组成的哈希set为键,但由于题中的节点是从0开始的数字,我们可以用 List 来代替,索引就是键。
  • 最长路径的中间节点最多会有两个:最长路径有奇数个节点,则中间节点有 1 个;最长路径有偶数个节点,则中间节点有 2 个。
  • 基本思路是:找到所有的叶子节点,去掉所有叶子节点,找到新的所有叶子节点,去掉所有叶子节点 ... 直到剩下的节点个数小于等于2个。


# -*- coding: utf-8 -*-
# @Author:             何睿
# @Create Date:        2019-02-17 13:46:09
# @Last Modified by:   何睿
# @Last Modified time: 2019-02-17 14:15:30
class Solution:
    def findMinHeightTrees(self, n: 'int',edges: 'List[List[int]]') -> 'List[int]':
        # 如果只有一个节点,直接返回当前节点
        if n == 1: return [0]
        # 路径:记录每个节点可以访问到的所有节点 type:list[set()]
        # 更一般的情况是利用字典实现,利用节点作为键,节点能够走到的所有节点
        # 组成的set作为值,但是题中得节点为从0开始的数值,因此可以用list代替字典
        paths = [set() for _ in range(n)]
        #  找到每个节点可以走到的下一个节点
        for node1, node2 in edges:
            paths[node1].add(node2)
            paths[node2].add(node1)
        # 找到所有的叶子节点
        leaves = [node for node in range(n) if len(paths[node]) == 1]
        # root用于记录剩下的节点
        roots = n
        while roots > 2:
            # 更新剩下的节点个数
            roots -= len(leaves)
            # 新的叶子节点
            newleaves = []
            for node in leaves:
                # 获取叶节点的父节点
                parent = paths[node].pop()
                # 从叶节点的父节点中删除当前节点
                paths[parent].remove(node)
                # 如果当前节点的父节点只能访问一个节点,则添加到新叶节点中
                if len(paths[parent]) == 1: newleaves.append(parent)
            leaves = newleaves
        return leaves


源代码文件在这里.


目录
相关文章
Leetcode Minimum Depth of Binary Tree (面试题推荐)
计算树的最小深度 很简单的一道题,只需要遍历一次树,到叶子节点的时候计算一下深度和当前最小深度比较,保存最小值就行。 我在这用了一个全局变量 mindepth。总感觉我这代码写的不够简练,求更精简的方法。
47 0
LeetCode Contest 178-1368. 使网格图至少有一条有效路径的最小代价 Minimum Cost to Make at Least One Valid Path in a Grid
LeetCode Contest 178-1368. 使网格图至少有一条有效路径的最小代价 Minimum Cost to Make at Least One Valid Path in a Grid
LeetCode 433. Minimum Genetic Mutation
现在给定3个参数 — start, end, bank,分别代表起始基因序列,目标基因序列及基因库,请找出能够使起始基因序列变化为目标基因序列所需的最少变化次数。如果无法实现目标变化,请返回 -1。
67 0
LeetCode 433. Minimum Genetic Mutation
LeetCode 209. Minimum Size Subarray Sum
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组。如果不存在符合条件的连续子数组,返回 0。
116 0
LeetCode 209. Minimum Size Subarray Sum
LeetCode 111. Minimum Depth of Binary Tree
给定一棵二叉树,返回其最短深度. 题目要求是返回一颗二叉树从根节点到到所有叶节点中,深度最小的值.
78 0
LeetCode 111. Minimum Depth of Binary Tree
LeetCode 64. Minimum Path Sum
给定m x n网格填充非负数,找到从左上到右下的路径,这最小化了沿其路径的所有数字的总和。 注意:您只能在任何时间点向下或向右移动。
102 0
LeetCode 64. Minimum Path Sum
|
人工智能 算法
LeetCode 1347. 制造字母异位词的最小步骤数 Minimum Number of Steps to Make Two Strings Anagram
LeetCode 1347. 制造字母异位词的最小步骤数 Minimum Number of Steps to Make Two Strings Anagram
|
Python
[Leetcode][python]Unique Binary Search Trees/不同的二叉查找树
题目大意 给出一个n,求1-n能够得到的所有二叉搜索树
98 0
|
机器学习/深度学习
Leetcode-Medium 96.Unique Binary Search Trees
Leetcode-Medium 96.Unique Binary Search Trees
97 0
|
索引
LeetCode 599: 两个列表的最小索引总和 Minimum Index Sum of Two Lists
题目: 假设 Andy 和 Doris 想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示。 Suppose Andy and Doris want to choose a restaurant for dinner, and they both have a list of favorite restaurants represented by strings. 你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅。
881 0