我知道Tortoise和Hare的会议总结了循环的存在,但是如何将兔子移动到链接列表的开头同时将野兔保持在会场,然后一步一步地移动两个步骤使它们在循环的起始点相遇?
我已经看过一个问题,讨论在链表中查找循环的算法.我已经阅读了Floyd的循环寻找算法解决方案,在许多地方提到我们必须采取两个指针.一个指针(慢/龟)增加一个,其他指针(更快/野兔)增加2.当它们相等时我们找到循环,如果更快的指针到达null,则链表中没有循环.
现在我的问题是为什么我们将指针增加更快2.为什么不是别的呢?增加2是必要的,或者我们可以将它增加X来得到结果.如果我们将指针增加2,或者可能存在需要增加3或5或x的情况,我们是否有必要找到一个循环.
algorithm linked-list cycle data-structures floyd-cycle-finding
我看了一些面试问题,在网上关于你如何发现是否有一个链表一环,和解决方案(Floyd的循环查找算法)是有两个指针,一个是比其他快2倍,并检查他们再次相遇.
我的问题是:为什么我不能只保持一个指针固定,只是每次将另一个指针向前移动1步?
据我所知,为了检测链表中的循环,我可以使用Hare和Tortoise方法,它有2个指针(慢速和快速).但是,在阅读了wiki和其他资源之后,我不明白为什么保证这两个指针在O(n)时间复杂度上会满足.
根据弗洛伊德的循环寻找算法,乌龟和野兔会面的点解释了链接列表中的循环性质.
为了在循环中找到起始节点,我们初始化指向列表头部的指针,并开始将野兔和乌龟指针递增一个单位.它们相遇的点表示循环的起始节点.
请告诉我它如何适用于特定情况.
链接列表如下:
1->2->3->4->5->6->7->8->3
Run Code Online (Sandbox Code Playgroud) 如何检测无限序列中的重复数字?我试过Floyd&Brent检测算法,但什么都没有......我有一个生成器,产生0到9(含)的数字,我必须认识到它的一个时期.
示例测试用例:
import itertools
# of course this is a fake one just to offer an example
def source():
return itertools.cycle((1, 0, 1, 4, 8, 2, 1, 3, 3, 1))
>>> gen = source()
>>> period(gen)
(1, 0, 1, 4, 8, 2, 1, 3, 3, 1)
Run Code Online (Sandbox Code Playgroud) 我想将以下Haskell代码转换为Agda:
import Control.Arrow (first)
import Control.Monad (join)
safeTail :: [a] -> [a]
safeTail [] = []
safeTail (_:xs) = xs
floyd :: [a] -> [a] -> ([a], [a])
floyd xs [] = ([], xs)
floyd (x:xs) (_:ys) = first (x:) $ floyd xs (safeTail ys)
split :: [a] -> ([a], [a])
split = join floyd
Run Code Online (Sandbox Code Playgroud)
这使我们能够有效地将列表拆分为两个:
split [1,2,3,4,5] = ([1,2,3], [4,5])
split [1,2,3,4,5,6] = ([1,2,3], [4,5,6])
Run Code Online (Sandbox Code Playgroud)
所以,我试图将此代码转换为Agda:
floyd : {A : Set} ? List A ? List A ? List …Run Code Online (Sandbox Code Playgroud) haskell functional-programming theorem-proving agda floyd-cycle-finding
我读了关于链表检测算法的循环 ,我怀疑
1)如何检测"会议元素".例如,在以下情况中 - 如何检测会议是否在第3个元素?
2)如何检测列表的长度(如果超过 - 6)
运行时间O(n),存储器O(1)中的两个问题.
我试图在.NET上用C++找到这个算法,但不能,我找到了这个:
// Best solution
function boolean hasLoop(Node startNode){
Node slowNode = Node fastNode1 = Node fastNode2 = startNode;
while (slowNode && fastNode1 = fastNode2.next() && fastNode2 = fastNode1.next()){
if (slowNode == fastNode1 || slowNode == fastNode2) return true;
slowNode = slowNode.next();
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
但似乎不对,或者我错了?我怎么能真正证明我的野兔最终会遇到乌龟?提前感谢任何解释它是如何工作的proof
关于这个解决方案,我发现在常规算法中他们只使用一个快速迭代器,但在这里他们使用两个,为什么?
我今天正在通过Floyd的循环查找算法并且有疑问.为什么他需要两个指针并以不同的速度移动它们?
他可以改为创建两个指针,保持一个静态,并将它的指针与另一个指针进行比较,然后递增?我的意思是,即使这样也会导致找到合适的周期?