uacs2024

导航

leetcode142-环形链表 II

142. 环形链表 II

 

方法一:快慢指针

先通过快指针和慢指针判断是否有环,无环则返回NULL.

有环:

 

 

 

 概括来说就是:f 代表快指针走了几步,s 代表慢指针走了几步。则有 f = 2s  ;  f = s + nb ; (b代表环的结点个数,n代表快指针比慢指针多走几个环的长度)

                              两式联立得,f = 2nd  ;   s = nb   ;

       如果让慢指针再走从起始结点到环入口的距离a,慢指针将回到环入口,即 s2 = a + nb;

       如何知道起始结点到环入口的距离a?可以让一个指针从起始结点不断向前走一步,和慢指针相遇的地方就是环的入口。这里我们使用快指针每次走一步。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode *dummyHead = new ListNode;
        dummyHead->next=head;
        ListNode *slow=dummyHead;
        ListNode *fast=dummyHead;
        while(slow&&fast&&fast->next)
        {
            slow=slow->next;
            fast=fast->next->next;
            if(slow==fast)  break;
        }
        if(!(slow&&fast&&fast->next))   return NULL;
        fast = dummyHead;
        while(fast!=slow)
        {
            fast=fast->next;
            slow=slow->next;
        }
        return slow;
};

方法二:哈希表?集合?如果出现第一个已在集合中的结点,那它就是环的入口

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        unordered_set<ListNode*> code;
        while(head)
        {
            if(code.count(head))    return head;
            code.insert(head);
            head=head->next;
        }
        return NULL;
    }
};

 

posted on 2022-09-14 19:37  ᶜʸᵃⁿ  阅读(11)  评论(0编辑  收藏  举报