1. 程式人生 > >面試題56:連結串列中環的入口節點

面試題56:連結串列中環的入口節點

      題目:一個連結串列中包含環,請找出該連結串列的環的入口結點。

    這道題藉助於前面的連結串列的倒數第K個節點的思想,考慮快慢指標。考慮當知道了連結串列的環中所含的節點數目,用一個快指標先走這麼多個節點,再用慢指標,兩個同時走,此時他們相遇的第一個節點就是連結串列的入口節點。下面問題就轉換為求連結串列環的節點數目。

    考慮連結串列是否成環,同樣用快慢指標,當他們相遇的那個節點,肯定是環內的節點,再讓它自己一步步走,等再次走到這個節點即可求到環的大小。

     程式碼如下:

struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};

class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
        if(pHead == NULL)
            return pHead;
        int len=LengthOfRing(pHead);
        if(len == 0)
            return NULL;
        ListNode *slow=pHead;
        ListNode *fast=pHead;
        int num=0;
        while(num < len)
        {
            fast = fast->next;
            num++;
        }
        while(slow != fast)
        {
            slow = slow->next;
            fast = fast->next;
        }
        return slow;
    }
    int LengthOfRing(ListNode* pHead)
    {
        ListNode *fast=pHead;
        ListNode *slow=pHead;
        int num=0;
        fast = fast->next->next;
        slow = slow->next;
        if(slow == NULL)
            return 0;
        while(fast != NULL && slow != NULL)
        {
            if(fast == slow)
                break;
            slow = slow->next;
            fast = fast->next;
            if(fast != NULL)
                fast = fast->next;
        }
        if(fast == NULL)
            return 0;
        else 
        {
            ListNode *temp = slow->next;
            num++;
            while(temp != slow)
            {
                num++;
                temp = temp->next;
            }
            return num;
        }
            
    }
};
     這裡要注意快慢指標那對於fast和slow是否為NULL的判斷,否則測試段錯誤。