1.链表中是否存在环形结构
首先这种题目我们要想到两个快慢指针
struct ListNode *fast 和 struct ListNode *slow
两个指针都指向头节点开始往后走
fast一次走两步
slow一次走一步
如果链表中有环那么这两个指针将会相遇
代码如下
bool hasCycle(struct ListNode *head) {
struct ListNode*quick=head;
struct ListNode*slow=head;
while(quick&&quick->next)
{
quick=quick->next->next;
slow=slow->next;
if(slow==quick)
{
return true;
}
}
return false;
}
2.链表中是否存在环形结构并且返回开始入环时第一个节点
首先!!!!!这是一个需要计算的题目
只有通过计算我们才能得出思路!!!!!
让我们看上面那个图像
假设非环形链表长L
环形链表长C
快慢指针fast和slow相遇点是meet
入环节点和meet相距N
我们知道快指针fast走的路程是slow的两倍 假设fast比slow多走了n圈
所以可以得出等式 L+N+n*C=2*(L+N) =>> L+N+(n-1)*C+C=2*(L+N)
解等式两边得 C=L+N
转换得C-N=L
所以我们可以在fast和slow相遇位置设置一个节点meet
meet和head同时从当前位置移动每次走一步
当meet和head相遇时所在节点为进入环的节点
代码如下
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode *fast=head;
struct ListNode *slow=head;
while(fast && fast->next)
{
fast=fast->next->next;
slow=slow->next;
if(slow==fast)
{
struct ListNode * meet=slow;
while(meet!=head)
{
meet=meet->next;
head=head->next;
}
return head;
}
}
return NULL;
}