Leetcode第142題——環形鏈表2

給定一個鏈表,返回鏈表開始入環的第一個節點。 如果鏈表無環,則返回 null。

爲了表示給定鏈表中的環,我們使用整數 pos 來表示鏈表尾連接到鏈表中的位置(索引從 0 開始)。 如果 pos 是 -1,則在該鏈表中沒有環。注意,pos 僅僅是用於標識環的情況,並不會作爲參數傳遞到函數中。 說明:不允許修改給定的鏈表。
在這裏插入圖片描述

解題思路:
1.使用快慢指針判斷有無環:讓慢指針每次走一步,快指針每次走倆步。

不理解爲什麼快慢指針可以來判斷有無環的可以看上一篇博客:
環形鏈表1

slow = slow->next;
fast = fast->next->next;

2.當有環時:fast與slow會相遇,再讓頭結點head與相遇結點fast一起每次走一步,
head與fast相遇時,就是環的第一個結點。
如下圖所示:
A爲鏈表頭結點的位置,B爲入環結點的位置,C爲快慢指針相遇位置。
設AB=L,BC=X,圓環周長爲R。
CB=R-C
當快慢指針相遇時:慢指針slow的路程爲L+X
快指針爲L+X+nR
根據快指針走的路程時慢指針走的二倍:
2(L+X) = L+X+n

R
化解得:L = n*R-X
L = (n-1)R + (R-X)








在這裏插入圖片描述

代碼實現:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) {
   
   
    //創建快慢指針slow,fast
    struct ListNode* slow = head,*fast = head;

    //判斷是否有環
    while(fast && fast->next)
    {
   
   
        slow = slow->next;//慢指針每次走一步
        fast = fast->next->next;//快指針每次走倆步

        if(fast == slow)
        {
   
   
            break;//相遇跳出
        }
    }

    if(fast == NULL || fast->next == NULL)//判斷無環的情況
    {
   
   
        return NULL;
    }

    //有環
    while(head != fast)//fast從與slow相遇的結點走,head從頭開始走,head與fast相遇點就是環的頭結點
    {
   
   
        head = head->next;
        fast = fast->next;
    }
    
    return head;

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章