题目:
题目链接:
https://leetcode-cn.com/problems/linked-list-cycle-ii/
题解
题解1:
- 取巧法:主要利用leetcode的链表地址由于是由低到高的变化的,如果有环则head->next一定小于head。
题解2:
- 双指针法:快慢指针,先判断是否有环,若有环则快慢指针相遇,那么此时我们需要将fast还原至链表头部,slow不变,然后二者每次走一步,最终二者的位置就是换的入口;若没有环,我们直接返回nullptr即可。关于数学公式的证明,大家看官方题解即可。
代码如下:
class Solution {
public:
//题解1:取巧法
ListNode *detectCycle(ListNode *head) {
//leetcode的链表地址由于是由低到高的变化的,如果有环head->next一定小于head
while(head)
{
if(head->next<=head)return head->next;
head=head->next;
}
return NULL;
}
};
class Solution {
public:
//题解2:快慢指针,先判断是否有环,若有环则快慢指针相遇,那么此时我们需要将fast还原至链表头部,slow不变,然后二者每次走一步,最终二者的位置就是换的入口;若没有环,我们直接返回nullptr即可。关于数学公式的证明,大家看官方题解即可。
ListNode *detectCycle(ListNode *head) {
//1、排除空节点或单个节点不成环的情况
if(!head||!head->next)return nullptr;
ListNode * slow=head->next,*fast=head->next->next;
//2、以下代码和141一样,判断是否存在环
while(fast!=slow)
{
//没有环,fast走到链表尾部,fast为空或者fast的next节点为空
if(!fast||!fast->next)return nullptr;
slow=slow->next;
fast=fast->next->next;
}
//3、找到相遇点了,将fast重置为head,slow不变,然后fast和slow现在开始每次只走一步,相遇点就是环的入口
fast=head;
while(fast!=slow)
{
fast=fast->next;
slow=slow->next;
}
return slow;
}
};