给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
说明:不允许修改给定的链表。
代码如下
struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB)//代码比较长其实
//只有三部分
{
int lenA = 0,lenB = 0,gap = 0;//找俩个链表的交点,看不懂的参考笔者前期博客
struct ListNode* a = headA;
struct ListNode* b = headB;
struct ListNode* meet = NULL;
while(a != NULL && a -> next != NULL)
{
lenA++;
a = a -> next;
}
while(b != NULL && b -> next != NULL)
{
lenB++;
b = b -> next;
}
if(b != a)
{
return NULL;
}
else
{
a = headA;b = headB;
if(lenA > lenB)
{
gap = lenA - lenB;
while(gap--)
{
a = a -> next;
}
}
else
{
gap = lenB - lenA;
while(gap--)
{
b = b -> next;
}
}
while(a && b)
{
if(a == b)
{
meet = a;
return a;
}
a = a -> next;
b = b -> next;
}
}
return meet;
}
struct ListNode *hasCycle(struct ListNode *head) {//判断这个链表中有没有环
if(head == NULL || head -> next == NULL) return false;
struct ListNode* slow = head;
struct ListNode* fast = head -> next;
while(slow != fast)
{
if(fast == NULL || fast -> next == NULL)
{
return NULL;
}
slow = slow -> next;
fast = fast -> next -> next;
}
return fast;
}
struct ListNode *detectCycle(struct ListNode *head) {//把俩个函数调用的主逻辑
struct ListNode* h = NULL;
struct ListNode* Union = NULL;
struct ListNode* meet = hasCycle(head);
if(meet == NULL)
{
return NULL;
}
else
{
h = meet -> next;
meet -> next =NULL;
Union = getIntersectionNode(head,h);
return Union;
}
}
这种办法就是将我们之前练习的俩个函数组合起来,接下来我们来看看方法二
struct ListNode *hasCycle(struct ListNode *head) {
if(head == NULL || head -> next == NULL) return false;
struct ListNode* slow = head;
struct ListNode* fast = head -> next;
while(slow != fast)
{
if(fast == NULL || fast -> next == NULL)
{
return NULL;
}
slow = slow -> next;
fast = fast -> next -> next;
}
return fast;
}
struct ListNode *detectCycle(struct ListNode *head) {
struct ListNode* meet = hasCycle(head);
if(meet == NULL)
{
return NULL;
}
else
{
while(1)//一点有相交节点所以可以写成1
{
if(meet == head)
{
return meet;
}
meet = meet -> next;
head = head -> next;
}
}
return;
}
ps:如果有什么问题欢迎留言与笔者讨论。