本题的突破点是:任何一个节点node,它到其他任意节点的距离里最长的那条,一定是通向这棵树的直径的一个端点。也就是说,假设这棵树的直径是AB(直径指的是这棵树最长的一条end-end的距离)。那么任意一个节点C,它到其他任意节点的距离里最长的那条,一定是走向A或者走向B的。
在本题中,我们就选定1号节点。看其他所有节点里离1最远的是哪一个?找到这个节点之后,它一定是A和B中的一个。假设是A,那么我们就只要再调用一次dis(A, AllTheOtherNodes)就可以得到AB之间的距离(也就是直径)。
于是问题变成:选定1号节点,如何确定其他所有节点里离1最远的是哪一个?根据所给的API的定义,其实很好确定,只要将candidate poll不断二分即可。最初时这个poll是[2,N],将poll二分为poll_1和poll_2,根据dis(1,poll_1)和dis(1,poll_2)的大小,选择较大的那个就是A点所在的poll。于是重复这个过程,直至这个poll只有一个元素。
注意,上面的方法每个回合要调用两次dis。我们可以事先算出maxDis = dis(1,[2,N])
,然后每次将poll二分之后,只要判断poll_1或者poll_2是否与maxDis相等即可推算接下来范围缩小至哪一半。这样每个回合只需要调用一次dis.