LeetCode 310. Minimum Height Trees

题目描述

出处 https://leetcode.com/problems/minimum-height-trees/description/

For a 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]


分析

这道题的目的是求无向图中高度最小的树,在一个不存在环的无向图中,高度最小的树的根只有一个或两个,若存在三个,则三点必构成一条链,中间的点所对应的树高度会更小,以此类推。

  • 方法一:可以通过暴力求解的方式,对无向图中每一个点采用深度搜索,从而获得每一个点作为树的根时对应的树的高度,找到高度最小的树。但这种方法的过于复杂,会导致超时。
  • 方法二:通过对问题进行分析,寻找高度最小的树,就是寻找最中心的点,则可以循环删除所有叶节点,最终留下的点则为所求根。

最终结果

方法一:

class Solution {
public:
    int max = 0;
    void dfs(int num, int depth, int n, int* graph, int visit[]) {             
        visit[num] = 1;
	    if (depth > max) max = depth;
        for(int i = 0; i < n; i++) {
            if (visit[i] == 0 && graph[num*n+i] == 1) {                            
                dfs(i, depth+1, n, graph, visit);
            }
        }
        return;
    }
    
    vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {
        vector<int> count(n);
        int graph[n][n] = {0};
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                graph[i][j] = 0;
            }
        }
        for (vector<pair<int, int>>::iterator it = edges.begin(); it != edges.end(); it++) {
            graph[(*it).first][(*it).second] = 1;
            graph[(*it).second][(*it).first] = 1;
        }
        
        
        for (int i = 0; i <n; i++) {
            int visit[n] = {0};  
            int depth = 0;
            max = 0;
            dfs(i, depth, n, (int*)graph, visit); 
            count[i] = max;
        }
        
        vector<int> result;
        int min = count[0];
        for (int i = 0; i < n; i++) {
            if (count[i] < min) {
                min = count[i];
                result.clear();
                result.push_back(i);
            } else if (count[i] == min) {
                result.push_back(i);
            }
        }
        return result;
    }
     
};

方法二:

class Solution {
public:
    vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {
        vector<vector<int>> list(n);
        vector<int> degree(n);
        vector<int> res;
        
        for (auto& p: edges) {
            list[p.first].push_back(p.second);
            degree[p.first] ++;
            list[p.second].push_back(p.first);
            degree[p.second] ++;
        }
        
        while (n > 2) {          
            vector<int> del;
            for (int i = 0; i < degree.size(); i++) {
                if (degree[i] == 1)
                    del.push_back(i);
            }
            
            for (auto p: del) {
                degree[p] = -1;
                n --;
                for (auto t: list[p]) {
                    degree[t] --;
                }
            }
        }
        
        for (int i = 0; i < degree.size(); i++) {
            if (degree[i] >= 0) 
                res.push_back(i);
        }
        
        return res;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_36159989/article/details/82822564