本题表面上是关于图、关于树,本质上我觉得更像BFS,或者说树的level order traversal.
本题的意思是,想从一棵树的一群nodes里找出一个node作为根,使得从这个根节点出发,发散到周围的叶子节点的路径范围最短。可以想见,这个根节点必然得尽可能地位于“中央”。如何确定“中央”的位置呢?我们其实可以反其道而行之,从“边疆”出发往内地进军。从所有的叶子节点(入度为1、出度为0)同步出发,一步一步地往前走,那么它们的最终汇合点,必然就是最“中央”的地方。
很明显,这就是一棵树的层级遍历 (level order tranversal)。传统的树操作都是从root开始的(因为通常只给你一个root),必须从顶往底用队列的结构一层一层遍历。但这里给出了图的表述,这样我们就可以轻易地找出哪些是最底端的叶子节点,从叶子节点反推上去。
基本的算法思想就是BFS,具体的做法很像拓扑排序,可以参见269.Alien Dictionary.我们要借助一个Hash表记录所有节点的度.每次我们将度为1(说明是叶子节点或边缘节点)加入队列.队列每弹出一个元素,我们就找这个元素的相邻节点,将它们的度都减一,一旦减至1(说明这个节点被砍成了边缘节点),就可以把这个节点加入队列.
直到什么时候停止呢?直到所有已弹出的元素数目,加上已经加入队列的元素数目,恰好等于n为止.这时候,队列的元素数目,要么为1,要么为2,这一个或两个元素就是答案.
注意:为什么最后会有一个或两个元素可以作为答案。我也是看网上参考才知道的。不过这也非常好理解。如果最后还剩下三个连通的节点(因为这是一棵树,必然彼此连通),显然还有从两边“往中央进军”的余地,必然只有一个是中央;如果最后还剩下两个连通的节点,两边各进一步的话就僵持住了,显然可以是并列的“中央”