环形链表1:
思路:给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。来源:力扣(LeetCode)
利用快慢指针的思想,起初二者均指向头指针,慢指针走一步,快指针走两步,这样的话快指针要比满指针先入环,如果没有环的话,那样满指针永远都不会追上慢指针;但如果有环的话,慢指针终究会追上快指针。
具体代码如下:
typedef struct ListNode node;
bool hasCycle(struct ListNode *head)
{
node* fast=head;
node* slow=head;
while(fast && fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
return true;
}
return false;
}
但此时一定会有人有疑问,为什么快指针非要走两步,如果是走三步、四步呢?
一.如果是走两步假设slow进入圈后,slow与fast的距离为N,那么slow与fast之间的距离就会减少1,以此类推,最后二者就会相遇。
二.如果是走三步此时fast一次三步,slow一次走两步,二者之间距离会减少2,,当N为偶数时,二者一定会追上;如果N为奇数时,二者的距离到最后的距离会变为-1,那么他们的距离就会变为环的大小减1,那么二者终究不会相遇。
题目原型:环形链表2:
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。来源:力扣(LeetCode)
思路一:
首先我们要知道,慢指针进入环后,快指针一定在一圈之内追上了慢指针,只是为什么呢?
因为如果慢指针走了一圈,哪末快指针一定已经走了两圈,所以二者不可能错过,即慢指针最多走半圈,快指针就追上来了。
假设环外的长度为L,环内慢指针走的路程为X,哪样慢指针走的路程为L+X,哪快指针走的路程为多少呢?
则快指针走的路程为L+kC+X,C为环的长度,k为慢指针未进入环前快指针绕环的圈数,有上述条件我们知道快指针走的路程为慢指针的两倍,,所以有以下方程:2*(L+X)=L+k*C+X,化解有:
L=k*C-X
由此方程可知一个指针从头结点出发,另一个指针从快慢指针相遇位置出发,那么二者会相遇于入环的位置,由此思路便可开始编写代码。
具体代码如下:
typedef struct ListNode node;
struct ListNode *detectCycle(struct ListNode *head)
{
node* fast=head;
node* slow=head;
while(fast && fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
{
node* meet=slow;
while(meet!=head)
{
meet=meet->next;
head=head->next;
}
return meet;
}
}
return NULL;
}
思路二:
利用相交链表的思想,将此链表分为两个链表,二者相交的节点即为进入节点的位置,第一个链表为以快慢指针为头结点,第二个链表为以慢指针下一个节点为头节点的链表。
具体代码如下:
typedef struct ListNode node;
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)
{
node* curA=headA;
int countA=0;
while(curA)
{
curA=curA->next;
countA++;
}
node* curB=headB;
int countB=0;
while(curB)
{
curB=curB->next;
countB++;
}
node* longlist=headA;
node* shortlist=headB;
if(countAnext;
}
while(longlist)
{
if(longlist==shortlist)
return longlist;
longlist=longlist->next;
shortlist=shortlist->next;
}
return NULL;
}
node *detectCycle(node *head)
{
node* fast=head;
node* slow=head;
while(fast && fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
{
node* meet=slow;
node* newcode=slow->next;
meet->next=NULL;
return getIntersectionNode(head,newcode);
}
}
return NULL;
}
希望文章对您有帮助!!!



