【LeetCode】310. Minimum Height Trees

来源:互联网 发布:淘宝自制护肤品北海 编辑:程序博客网 时间:2024/04/30 14:58

题目链接


思路

我想到了n个点构成树,那么一定会有n-1条边,构成的树深度最大的情况发生在所有点位于一条链上,此时深度为 n/2n/2+1 ,这取决于n的奇偶性。

树深度最浅的情况发生在一个根节点,所有其它节点都与根节点直接相连,此时深度为2。

我还发现一个规律,就是叶子节点的数目+树的最长路径为一定值,为节点数+2。这样统计出有多少个叶子节点后,再走最长路径的一半所到达的节点就是根节点。但是这个思路不能保证走最长路径的一半是正确的路径,所以这个方法没有再进行下去。

Hot解法是利用bfs,从叶子节点开始访问,每一次循环都把与叶子节点直接相连的节点访问,并判断它们是否成为新的叶子节点。同时从叶子节点出发,最终共同到达的节点一定是根节点。


代码

vector<int> findMinHeightTrees(int n, vector<pair<int, int>>& edges) {        vector<int> re;        if (n<=2){            for (int i=0;i<n;++i){                re.push_back(i);            }            return re;        }        vector<unordered_set<int>> graph(n);        for (int i=0;i<edges.size();++i){            auto p = edges[i];            graph[p.first].insert(p.second);            graph[p.second].insert(p.first);        }        //find all leaves        queue<int> leaves;        for (int i=0;i<n;++i){            if (graph[i].size()==1) leaves.push(i);        }        while(n>2){            n = n - leaves.size();            queue<int> newLeaves;            while (!leaves.empty()){                int curLeaf = leaves.front();                leaves.pop();                int nextToLeaf = *(graph[curLeaf].begin());                graph[nextToLeaf].erase(curLeaf);                if (graph[nextToLeaf].size()==1){                    newLeaves.push(nextToLeaf);                }            }            leaves = newLeaves;        }        while (!leaves.empty()){            int leaf = leaves.front();            leaves.pop();            re.push_back(leaf);        }        return re;    }

细节

第一次我用向量存储每个节点的相邻节点,后来发现vector删除指定大小的元素不是很方便,vector只有两种删除方式,erase是删除基于位置的,pop_back()只能删除最后一个元素。所以后来改用set

0 0