我正试图找到循环开始的单链接列表的要点。 我想到的是2个指针*慢,*快速移动速度是其他速度的两倍。 如果列表有一个循环,那么在某些时候
5-6-7-8
| |
1-2-3-4-7-7
慢=快
是否可以有另一个优雅的解决方案,以便列表只遍历一次?
答案 0 :(得分:4)
你想要使用两个步行器,一个速度是另一个步行速度的两倍,但是这个问题的根本问题是你选择了一个合适的数据结构吗?您应该问自己是否真的需要找到中点,如果是,那么在O(1)(常数)时间内哪些其他结构可能更适合实现这一点?数组肯定会为集合的中点提供更好的性能,但其他操作速度较慢。在不知道其他情况的情况下,我无法提出任何其他建议,但我建议您检查一下您的要求。
答案 1 :(得分:2)
我假设这个单链表以NULL结尾。在这种情况下,慢速指针和快速指针将起作用。因为快速指针在速度慢的情况下是双倍的,如果快速指针到达列表的末尾,则慢速指针应位于其中间。
答案 2 :(得分:2)
我认为这是某种面试问题。
如果您的列表有循环,那么要在单次遍历中执行此操作,您需要将节点标记为已访问,因为快速步行者会通过列表。当快速步行者遇到NULL或已经访问过的节点时,迭代可以结束,而你的慢步行者则处于中点。
有许多方法可以将节点标记为已访问,但可以使用外部地图或集合。如果直接在节点本身标记节点,则需要进行另一次遍历来清理标记。
编辑:所以这不是关于找到中点,而是关于循环检测而不重新访问已访问过的节点。标记也适用于此。只需遍历列表并标记节点。如果你点击NULL,没有循环。如果您访问了受访节点,则会出现循环。如果标记也包含计数器,您甚至可以知道循环的开始位置。