LCR 022. 环形链表 II
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode *detectCycle(struct ListNode *head) { if(head == NULL || head->next == NULL) { return NULL; } struct ListNode *slow = head; struct ListNode *fast = head; while(fast && fast->next != NULL) { slow = slow->next; fast = fast->next->next; //相遇 if(slow == fast) { //交点 struct ListNode *meet = slow; while(meet != head) { meet = meet->next; head = head->next; } return meet; } } return NULL; }
方法2
复杂度
Code
思路
利用环形链表,找到相遇点
再利用链表相交
解题过程
找到相遇点
把相遇点的next创建为新链表newlist
再把相遇点的next置空
这样就形成两条链表
再利用所学的链表相交找到相交点
(实现复杂,证明简单)
复杂度
时间复杂度: O ( N ) O(N) O(N)
间复杂度: O ( 1 ) O(1) O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode *detectCycle(struct ListNode *head) {
if(head == NULL || head->next == NULL)
{
return NULL;
}
struct ListNode *slow = head;
struct ListNode *fast = head;
while(fast && fast->next != NULL)
{
slow = slow->next;
fast = fast->next->next;
//相遇
if(slow == fast)
{
//利用链表相交,相遇点尾节点置空
struct ListNode *newHead = slow->next;
fast->next = NULL;
struct ListNode *tail1 = head;
struct ListNode *tail2 = newHead;
int length1 = 1;
while(tail1->next)
{
tail1 = tail1->next;
length1++;
}
int length2 = 1;
while(tail2->next)
{
tail2 = tail2->next;
length2++;
}
if(tail1 != tail2)
{
//如果不相遇
return NULL;
}
struct ListNode *longlist = head;
struct ListNode *shortlist = newHead;
if(length1 <length2)
{
longlist = newHead;
shortlist = head;
}
//长的先走差距步,再同时找相交点
int gap = abs(length1 - length2);//#include<stdlib.h>
while(gap--)
{
longlist = longlist->next;
}
while(longlist != shortlist)
{
longlist = longlist->next;
shortlist = shortlist->next;
}
return longlist;
}
return NULL;
}