Floyd's Tortoise and Hare & 环检测算法

算法推导

image

hare的移动速度是tortoise的 2 倍,
设起始点到环的入口的距离是T,环的长度是C
tortoise第一次走到环的入口entry point时,我们假设这是tortoisehare之间的在环上的距离是r
start point开始出发到tortoise第一次走到环的入口时,hare移动的距离是 T + r + k*C,k >= 0
又因为,hare移动的速度是tortoise的两倍,且这时tortoise移动的距离是T,所以hare移动的距离是 2T。
得到等式 A T + r + k*C = 2T,k >= 0
简化得到等式 B r + k*C = T,k >= 0

[图片上传失败...(image-1940ba-1559799507418)]
当 tortoise 第一次走到环的入口entry point时,而这时tortoisehare之间的距离是 r,
那么如果tortoise现在就不继续移动的话,hare还需要往前走C-r才能追上tortoise
但是hare在往前追赶tortoise的时候,tortoise也在移动,而hare的移动速度是tortoise的两倍,
所以hare可以追上tortoise,并且需要往前走2*(C-r)才能追上tortoise

image

hare移动了2*(C-r)的距离追上tortoise的时候,tortoise从相对于环的入口entry point移动了C-r

所以,在tortoisehare第一次在环上相遇时,环的入口entry point到这个点meet point的距离是C-r, 而从这个相遇点meet point再往前移动r,就又回到了环的入口entry point

haretortoise第一次相遇的这个时候,将haremeet point重新放到起始点start pointtortoise仍放在这个相遇点meet point
然后让它们以相同的速度开始移动,

根据等式 B r + k*C = T,k >= 0

tortoisehare必然会在环的入口点entry point再次相遇。

入口entry point找到后,就能很容易得到T
然后入口entry point,让tortoise停下,hare 继续跑一圈,就能得到 C

算法应用

  1. 链表有环检测
    两个指针,慢指针移动速度为 1,快指针移动速度为 2,判断两个指针是否相遇
  2. 找出有环链表的入口节点
    当两个指针相遇时,将其中一个指针重新放到链表头,然后让两个指针移动速度都为 1,当两个指针再次相遇,就找到了有环链表的入口节点
  3. 计算环长度
    在入口节点放置两个个指针,一个指针不动,一个指针移动速度为 1,两个指针相遇,就可计算出环的长度

算法实现

golang

  1. 链表有环检测 leetcode 141
/*
 * @lc app=leetcode id=141 lang=golang
 *
 * [141] Linked List Cycle
 */

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func hasCycle(head *ListNode) bool {
    if head == nil {
        return false
    }
    t, h := head, head
    started := false
    for h != nil && h.Next != nil {
        if t == h {
            if started {
                return true
            } else {
                started = true
            }
        }
        t = t.Next
        h = h.Next.Next
    }
    return false
}
  1. 找出有环链表的入口节点 leetcode 142
/*
 * @lc app=leetcode id=142 lang=golang
 *
 * [142] Linked List Cycle II
 */

/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func detectCycle(head *ListNode) *ListNode {
    var cycPoint *ListNode
    if head == nil {
        return cycPoint
    }
    t, h := head, head
    started := false
    hasCycle := false
    for h != nil && h.Next != nil {
        if t == h {
            if started {
                hasCycle = true
                break
            } else {
                started = true
            }
        }
        t = t.Next
        h = h.Next.Next
    }
    if hasCycle {
        h = head
        for h != nil && t != nil {
            if h == t {
                cycPoint = h
                break
            }
            h = h.Next
            t = t.Next
        }
    }
    return cycPoint
}

欢迎转载,请注明出处~
作者个人主页

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,612评论 5 471
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,345评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,625评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,022评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,974评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,227评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,688评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,358评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,490评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,402评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,446评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,721评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,802评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,013评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,504评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,080评论 2 341

推荐阅读更多精彩内容