一、已知一个链表,如何判断他有环呢?如果有返回ture ,如果没有返回false
本问题我们使用快慢指针来解决:
我们设定两个指针:fast和slow,fast的移动速度是slow的两倍,即fast移动两步,slow移动一步。
如果该链表不带环,则能保证fast始终位于slow前面,也就是fast和slow不会指向同一个节点。
但如果链表带环,在fast和slow指针进入环后,fast永远比slow多走一步,也就是说在slow走完一圈之前,fast就会和slow相遇,也就是指向同一节点,按照这个思路,我们可以写出一个函数:
typedef struct ListNode
{
int val;
ListNode* next;
}LN;
bool hasCycle(struct ListNode *head) {
LN*slow=head;
LN*fast=head;
while(fast&&fast->next)
{
fast=fast->next->next;
slow=slow->next;
if(fast==slow)
return true;
}
return false;
}
二、寻找入环节点
在上一题的基础上,我们看这个问题
通过一系列运算,我们发现L=(x-1)*C+(C-N);,这意味着如果我们重新设定两个指针,A指针从meet开始走,B指针从head开始走,他们一定会相遇在入环节点,由此思路我们写出一个函数:
typedef struct ListNode
{
int val;
struct ListNode* next;
} LN;
struct ListNode *detectCycle(struct ListNode *head) {
LN*slow=head;
LN*fast=head;
LN*meet=head;
while(fast&&fast->next)
{
fast=fast->next->next;
slow=slow->next;
if(slow==fast)
{
meet=slow;
while(head!=meet)
{
head=head->next;
meet=meet->next;
}
return meet;
}
}
return NULL;
}
本篇博客内容就到这里了,如果对你有所帮助的话,请点赞收藏关注哦!