整理部分双指针算法(重点:龟兔算法,含证明)

一、同速指针

问题:从单链表中找到倒数第n个结点。

直觉算法

遍历一遍链表,得到链表长度 length,然后指针重新指向表头,设置从 0 开始的计数器,指针每往后移动一个,计数器加 1 ,当计数器变为 length - n 时,就找到了倒数第 n 个结点。

双指针算法

使用两个指针,假设为 p、q,p 指向表头,q 先向后移动指向第 n 个结点。然后两个指针同时向后移动,直至 q 走到链表末尾。此时 p 就指向了倒数第 n 个结点。

二、快慢指针

问题一:查找单链表的二分位点

直觉算法

遍历链表获得链表长度,然后再计数获得中间结点。

快慢指针算法

使用两个指针,假设为 slow、fast,两者初始时都指向表头。slow 一次向前移动一个结点,fast 一次向前移动两个结点。当 fast 移动到链表末尾,slow 就指向了链表的中间结点。

问题二:判圈:如何检测一个单链表是否有环?如果有环,如何确定环的起点以及长度?

直觉算法

用哈希表保存已经走过的结点指针,查找判断当前指针是否在之前已经出现过。

龟兔算法(Floyd cycle detection)

龟兔其实是快慢指针,假设为 slow、fast,初始时都指向单链表表头,slow 指针每次移动一个结点,fast 指针每次移动两个结点。如果 slow、fast 相遇,则说明有环。如果 fast 走到链表末尾还没与 slow 相遇,则无环。

floyd.png

符号约定及定义: 约定单链表表头为 A,环起点为 B,龟兔相遇结点为 C。定义 |AB| 表示沿单链表方向结点 A 到结点 B 的距离,距离值的定义为乌龟走的步数,如图 |AB| = 3。环长为 L,表示乌龟从环起点出发回到环起点所走的步数。
令则从出发到相遇,乌龟所走的距离为:后面有证明乌龟不可能绕环超过一圈。
兔子所走的距离为:上面两式相减,并联立乌龟所走的距离得:由此可知,m+n是环长L的整数倍。

环起点: 当龟兔相遇后,令乌龟返回表头 A,兔子留在相遇结点 C,两者都一次向前移动一个结点(此时已是同速指针),此时乌龟往环的位置赶,兔子在环内转圈圈。当乌龟赶到环起点时,兔子也移动了 m,加上初始时距环起点的 n,兔子距环起点 m+n,为环长 L 的整数倍,此时兔子也刚好到达环起点,两者再次相遇,相遇结点就为环起点 B 。

环长度: 接着上一步,龟兔同时指向环起点,此时让两者中的一个留在 B,一个逐结点向前推进,并同步计数,当两者再次相遇就得到了环长 L。

证明快指针 fast 一定会追上慢指针 slow。

slow 在 fast 前一个结点时,两者经过一次移动两者相遇。
假设 slow 在 fast 前 k 个结点时,经过有限次移动两者一定会相遇。
则当 slow 在 fast 前 k+1 个结点时,经过一次移动,变为 slow 在 fast 前 k 个结点,则经过有限次移动两者一定会相遇。
得证。

证明慢指针 slow 绕环不可能超过一圈。
  1. 单链表本身为环的情况
    slow、fast 同时从环起点(表头)出发, 当 slow 绕环一圈时,由于D_{fast}=2D_{slow},fast 刚好绕环两圈,此时两者在环起点相遇。
    下面证明此前不可能相遇(出发时不算),即 slow 绕环一圈时是第一次相遇:
    假设 slow、fast 在此之前相遇,相遇结点和环起点的距离为n(0<n<L),则D_{slow}=n D_{fast}=n+Ln+L=2n\Rightarrow n=L与假设矛盾,故假设不成立。
  2. 单链表有环,但不全为环的情况
    考虑 fast 追上 slow 要走的最远距离是,fast 刚好在 slow 的前一个结点。
    首先证明这种极端情况不可能发生在 slow 的上一步已经在环内时:
    假设 slow 的上一步已经在环内,且在 slow 的当前步出现了上述极端情况。
    回退到上一步可以发现,slow、fast 已经相遇,算法结束。故假设不成立
    所以这种情况只能发生在 slow 刚进入环起点时,fast 在 slow 的前一个结点。
    此时相遇之前两者之间的距离小于情况一,所以在 slow 绕环一圈之前,两者就已经相遇。
效率分析

由于慢指针最多走一遍单链表,所以Floyd cycle detection的时间复杂度为O(n),空间复杂度为O(1)。与直觉算法相比少了哈希表的使用,降低了空间复杂度。

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

推荐阅读更多精彩内容