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:

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

    0
    |
    1
   / \
  2   3

return [1]

Example 2:

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

 0  1  2
  \ | /
    3
    |
    4
    |
    5

return [3, 4]

Note:

(1) 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.”

(2) The height of a rooted tree is the number of edges on the longest downward path between the root and a leaf.

问题分析
需要找到一些顶点,使其到其他任一顶点的最长距离最小。
受到discussion的启发。建立图后不断去掉最外层(相邻节点只有一个)的叶节点,倘若某次去除后顶点集为空,则最后一次所去除的所有顶点为所求的顶点。

class Solution {
public:
    vector<int> findMinHeightTrees(int n, vector< pair<int, int> >& edges) {
        vector<node*> nodes;
        for (int i = 0; i < n; i++) {
            nodes.push_back(new node(i));
        }
        for (int i = 0; i < edges.size(); i++) {
            nodes[edges[i].first]->neighbor.insert(nodes[edges[i].second]);
            nodes[edges[i].second]->neighbor.insert(nodes[edges[i].first]);
        }
        set<node*> leaves;
        set<node*> del;
        while(1) {
            for (vector<node*>::iterator i = nodes.begin(); i != nodes.end(); i++){

                if (((*i)->neighbor).size() <= 1) {
                    leaves.insert(*i);
                    if (((*i)->neighbor).size() == 1) del.insert(*(((*i)->neighbor).begin()));
                    nodes.erase(i);
                    i--;
                }

            }

            for (set<node*>::iterator i = del.begin(); i != del.end(); i++){
                for (set<node*>::iterator j = leaves.begin(); j != leaves.end(); j++) {
                    (*i)->neighbor.erase(*j);
                }
            }

            if (nodes.size() == 0) {
                vector<int> roots;
                for (set<node*>::iterator j = leaves.begin(); j != leaves.end(); j++) {
                    roots.push_back((*j)->num);
                    delete *j;
                }
                return roots;
            }
            for (set<node*>::iterator j = leaves.begin(); j != leaves.end(); j++) {
                delete *j;
            }
            leaves.clear();
            del.clear();
        }
    }
private:
    struct node{
        int num;
        set<node*> neighbor;
        node(int n): num(n) {}
    };
};

提交结果可以说是十分惨烈了…
66 / 66 test cases passed.
Status: Accepted
Runtime: 1025 ms
Your runtime beats 2.71 % of cpp submissions.

……..
其实这题真的花了好长时间AC….大大超过了预期…大概是对图还不熟悉….
至于为什么跑出来还是那么慢…再参考了一下其他的答案
主要是实现方式出了一些问题。
有过多多余的遍历操作和集合的操作。
要继续熟练吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值