图中有 N 个节点,由 N-1 条边连接。从一个节点到任何其他节点恰好有 1 条最短路径。节点从 1 到 N 编号。给定 Q 个查询,它们告诉源节点和目标节点。在经过这些 Q 条路径后找到访问次数最多的节点。例如,假设 Q=3 和 3 个查询是:
1 5
2 4
3 1
所以从节点 1 到节点 5,然后从节点 2 到节点 4,然后从节点 3 到节点 1。最后,在 Q 次查询之后找到访问次数最多的节点。找到每条路径并增加每个访问的节点计数是一种幼稚的方法。面试官让我优化一下。
图中有 N 个节点,由 N-1 条边连接。从一个节点到任何其他节点恰好有 1 条最短路径。节点从 1 到 N 编号。给定 Q 个查询,它们告诉源节点和目标节点。在经过这些 Q 条路径后找到访问次数最多的节点。例如,假设 Q=3 和 3 个查询是:
1 5
2 4
3 1
所以从节点 1 到节点 5,然后从节点 2 到节点 4,然后从节点 3 到节点 1。最后,在 Q 次查询之后找到访问次数最多的节点。找到每条路径并增加每个访问的节点计数是一种幼稚的方法。面试官让我优化一下。
优化通常涉及权衡;在某些情况下,一种算法明显优于另一种算法,但在另一些情况下,一种算法在某个方面(例如时间)更好,而另一种算法在不同方面(例如内存使用)更好。
在您的情况下,我猜您的面试官正在寻找一种方法来优化您开始接收查询后必须完成的处理量,即使这意味着您必须对图表进行更多预处理。我这么说的原因是“查询”这个词;为“在线”查询优化数据源是很常见的。(当然,(s)他可能不希望您自己决定这种权衡是可以的;相反,(s)他可能希望就不同类型的权衡进行对话。)
所以,考虑到这一点。. .
总体而言,这需要O ( N 2 ) 预处理,每个查询O ( Q ) 实时处理和O ( N ) 后处理。
如果N非常大,并且我们预计即使只有一小部分节点被访问过一次,那么我们可以通过忽略树中未访问的部分来加速后处理。这涉及维护一组作为路径端点的节点,然后以“自下而上”的方式进行后处理,从最深的此类节点开始,并且仅当访问的路径数量为该节点小于它是最不共同祖先的次数。如果我们用P表示不同端点的数量,用M表示不同访问节点的数量,那么这可以用类似O ( P log P + M)。