環形連結串列||(leetcode中級篇一百四十二題)
阿新 • • 發佈:2018-12-16
給定一個連結串列,返回連結串列開始入環的第一個節點。 如果連結串列無環,則返回 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:如果有什麼問題歡迎留言與筆者討論。