[leetcode]310. Minimum Height Trees

Posted on 2018-02-07 14:11  你猜我猜不猜你猜不猜  阅读(128)  评论(0)    收藏  举报

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:

Given n = 4edges = [[1, 0], [1, 2], [1, 3]]

        0
        |
        1
       / \
      2   3

return [1]

题目是说从无向图里找一个或几个节点做根节点,使得高度最小。

 

这题似乎可以一路反证法过去。。我说似乎是因为我没有严格证明。。。

首先这个节点是1个或者2个。考虑3个的情况,那么中间那个节点对左或右的高度肯定至少是另外两个节点高度+1,因此不成立。

考虑一个MHT树,由树最底层的叶节点出发可以得到一条最长路。

根节点一定在这棵树最长路上,不然,由于根节点不在最长路上,那么根节点到最底层叶节点的路径会增加,MHT树不成立。

再考虑根节点在这条最长路上的位置,由于要树高度最短,因此根节点一定是这条路上的中间节点。

 

因此解题的关键就是从叶节点出发找到一条最长路,输出中间节点。

 

这里有两个case要注意,一个是从任意叶节点出发不一定能找到最长路, 一个是遍历所有叶节点找最长路会超时。

给出的方法是从任意一个叶节点出发找到这个叶节点对应的最长路,再从这条路另一头的叶节点出发,如果得到的最长路长度相等,就停止,输出根节点

否则当长度更长时继续。

当然这个方法没有严格证明,,可能就是个小trick。。就这样还能超过83%的人的运行时间。。。。。

class Solution {
public:
    void dfs(vector<int> &re,vector<vector<int> > &g,int *statue,int pre_node,vector<int> &pre_list){
        if(g[pre_node].size()==1 && statue[g[pre_node][0]]==1){
            if(pre_list.size()>re.size())
                re=pre_list;
            return;
        }
        int tmp_node;
        for(int i=0;i<g[pre_node].size();i++){
            tmp_node=g[pre_node][i];
            if(statue[tmp_node]==1)
                continue;
            pre_list.push_back(tmp_node);
            statue[tmp_node]=1;
            dfs(re,g,statue,tmp_node,pre_list);
            pre_list.pop_back();
            statue[tmp_node]=0;
        }
    }
    vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {
        int *statue = new int[n];
//        int *no_node = new int[n];
        memset(statue,0,sizeof(int)*n);
//        memset(no_node,0,sizeof(int)*n);
        vector<vector<int> > g(n);
        vector<int> re,pre_list;
        int a,b;
        for(int i=0;i<edges.size();i++){
            a = edges[i].first;
            b = edges[i].second;
            g[a].push_back(b);
            g[b].push_back(a);
        }
        int next_node;
        for(int i=0;i<g.size();i++)
            if(g[i].size()==1) {
                next_node = i;
                break;
            }
        int long_path=0;
        while(n>1 && (re.size()>long_path || re.size()==0)){
            long_path=re.size();
            statue[next_node]=1;
//                no_node[g[i][0]]=1;
            pre_list.push_back(next_node);
            dfs(re, g, statue,next_node,pre_list);
            statue[next_node]=0;
            pre_list.pop_back();
            next_node=re.back();
        }



        if(re.size()==0)
            return vector<int> {0};
        if(re.size()%2==1)
            return vector<int> {re[re.size()/2]};
        if(re.size()%2==0){
            if(re.size()/2<re.size()/2-1)
                swap(re[re.size()/2],re[re.size()/2-1]);
            return vector<int> {re[re.size()/2-1],re[re.size()/2]};
        }

    }
};

  

 

博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3