【leetcode】141/142Linked List Cycle(Floyd判圈算法)
来源:互联网 发布:淘宝产品模板 编辑:程序博客网 时间:2024/05/18 02:55
题目概述:
141:给定一个单链表,判断是否有环
142:给定一个单链表,判断是否有环,若有返回环的起始结点,若没有返回null
考虑用O(1)空间复杂度的算法实现,用到了Floyd判圈算法(也叫龟兔赛跑算法)。
Floyd判圈算法是一个可以在有限状态机、迭代函数或者链表上判断是否存在环,以及求出该环的起点与长度的算法。
原理是如果存在环,那么从同一个起点出发,同时以不同速度前进的2个指针必定会在某个时刻相遇。
首先判断是否有环:
本题中可以采用一个慢指针和一个快指针,慢指针每次前进一个结点,快指针每次前进两个结点,速度差为1,若快指针后续结点为空,则说明没有环,若能够相遇则有环。
速度差为1保证了如果存在环则必定可以相遇,若速度差为其他值,速度差与环长恰有某种关系时可能永远无法相遇。
设环长为n,当慢指针指向环的起始结点时,快指针与慢指针相差最大结点数为n-1(快指针指向起始节点的后续结点),类似追及问题,慢指针也只要再移动n-1次则能够与快指针相遇,也就保证了时间复杂度为O(n)
接着考虑如何找到环的起始结点:
设链表头结点经过x个结点到达环的起始结点,再经过y个结点快慢指针相遇,环长为n
经过上面的讨论可以知道慢指针不会围绕环再走一圈,根据两指针速度关系有:2(x+y)=x+y+kn,即x+y=kn,k为正整数
相遇后令其中一个指针重新指向链表头结点,另一个指针位置不变,令两指针以相同速度移动,再次相遇时指向的结点就是环的起始结点
(头结点向后移动x个结点为环起始结点,x+y=kn即从环起始结点后y个结点处(最初相遇的结点)出发,经过x步可以重新回到环起始结点)
0 0
- LeetCode Linked List Cycle II(Floyd 判圈算法)
- 【leetcode】141/142Linked List Cycle(Floyd判圈算法)
- LeetCode Linked List Cycle (Floyd判圈算法)
- Floyd判圈算法(龟兔赛跑算法, Floyd's cycle detection)及其证明
- Cycle detection——Floyd判圈算法
- LeetCode.142(141) Linked List Cycle && Linked List Cycle (II)
- Floyd判圈算法
- Floyd判圈算法
- floyd判圈算法
- Floyd判圈算法
- Floyd 判圈 算法
- Floyd判圈算法
- Floyd判圈算法
- Floyd判圈算法
- floyd判圈算法
- Floyd 判圈算法
- UVA11549(Floyd判圈算法)
- LeetCode 141 Linked List Cycle(链表判环)
- tjut 5288
- c++第七次作业
- PHP中array_chunk的用法
- redis学习五 ------ redis高可用(sentinel)
- Picasso入门教程(十)图片旋转和变换
- 【leetcode】141/142Linked List Cycle(Floyd判圈算法)
- 第四周 求四个数的最大公约数
- c++实验7-最大公约数和最小公倍数
- 通过atos命令获取64位错误地址的调用栈
- meta属性详解
- tjut 5294
- ijkplayer ffmpeg android独立编译
- 信号量解决读写者问题
- Ibatis中#与$的区别?