1. 程式人生 > >LeetCode 310. Minimum Height Trees

LeetCode 310. Minimum Height Trees

目錄

題目描述

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;
    }
};