这里有一个问题,来自Sedgwick在他的优秀著作《Java算法》中(第3.54题)
给定单向链表中的一个节点链接,该链表不包含空链接(即每个节点要么链接到自身,要么链接到列表中的另一个节点),确定不同节点的数量,而不修改任何节点并且使用不超过常数内存空间。
如何做到呢?使用乌龟和兔子算法一次扫描整个链表来判断它是否以任何方式为循环,并再次扫描以找出列表何时变成循环状态,然后再次扫描以计算到达此位置的节点数? 对我来说听起来有点暴力,我想可能还有更优雅的解决方案。
这里有一个问题,来自Sedgwick在他的优秀著作《Java算法》中(第3.54题)
给定单向链表中的一个节点链接,该链表不包含空链接(即每个节点要么链接到自身,要么链接到列表中的另一个节点),确定不同节点的数量,而不修改任何节点并且使用不超过常数内存空间。
如何做到呢?使用乌龟和兔子算法一次扫描整个链表来判断它是否以任何方式为循环,并再次扫描以找出列表何时变成循环状态,然后再次扫描以计算到达此位置的节点数? 对我来说听起来有点暴力,我想可能还有更优雅的解决方案。
龟兔赛跑算法可以同时给出循环长度和循环开始前的节点数(分别为λ和μ)。
看看这个:链表中的循环问题
指针标记:在实践中,使用C结构实现链接 列表至少需要一个指针;在C语言中,这样的结构需要4字节对齐。因此, 最低有效位是零。当遍历列表时,您可以通过翻转最低有效位来将指针标记为已遍历。 第二次遍历是为了清除这些位。
只需记住你曾经去过哪里,如果你回到同一个节点,那么游戏就结束了。
尝试将条目存储在二叉树中,您的时间复杂度为O(N * log(N)),空间复杂度为O(N)
编辑
如果您不按指数顺序链接存储每个节点,则可以使用Log(N)空间复杂度。这意味着您存储第1、2、4、8、16个节点,然后如果您被击中,则必须从该点继续。此方法的时间复杂度为N * Log(n)^ 2
O(log N)
和O(1)
空间复杂度相差很远,两者并不接近。 - jason