主页:114514的代码大冒
(欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ )
文章目录
目录
前言
祝你武运昌隆
一、环形链表
描述:
示例:
思路:
设置快慢指针,快指针一次走两步,慢指针一次走一步,如果链表有环,那么快指针先进环,慢指针之后进环,并且快指针开始追赶慢指针,必定会相遇;如果链表没有环,那么快指针一定会走到空节点或者它的下一个节点为空(fast == NULL or fast->next == NULL)
如图:
代码:
bool hasCycle(struct ListNode *head) {
struct ListNode *fast = head;
struct ListNode *slow = head;
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
return true;
}
}
return false;
}
延伸:
fast走两步,slow走一步,在带环链表中,一定会相遇吗?为什么?
答:
一定,证明:
fast走X(X>2)步,slow走一步,在带环链表中,一定会相遇吗?为什么?
答:
不一定,我们先假设fast每次走3步,slow每次走一步,于是两指针进环后,N(两指针之间的距离)在每次前进中“-2” ,如图:
二、环形链表 II
示例:
前提:
思路:
代码:
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode * fast = head;
struct ListNode * slow = head;
struct ListNode * phead = head;
if(head == NULL)
{
return NULL;
}
if(head->next == NULL)
{
return NULL;
}
if(head->next == head)
{
return head;
}
fast = fast->next->next;
slow = slow->next;
while(fast && fast->next)
{
if(slow == fast)
{
break;
}
fast = fast->next->next;
slow = slow->next;
}
if((fast == NULL)||(fast->next == NULL))
{
return NULL;
}
struct ListNode * meet = slow;
while(meet != phead)
{
phead = phead->next;
meet = meet->next;
}
return meet;
}
上图的办法理解起来有些费力,这里提供一个更简便的方法
可以参考相交链表
写一写
总结
带环链表经常出现在面试题中,虽然不需要往深了探索,但是最基本的内容我们还是需要去掌握的
OK,这就是本次的全部内容了