142 环形链表II

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

说明:不允许修改给定的链表。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:tail connects to node index 1
解释:链表中有一个环,其尾部连接到第二个节点。

解法:

  • Hash表,遍历整个链表,把每个Node保存在列表中,当碰到某个结点已存在该链表中,即它为环形链表的入口。
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        if head == None: return None
        ls = []
        cur = head
        while cur:
            if cur in ls:
                return cur
            else:
                ls.append(cur)
            cur = cur.next
        return None
  • 双指针,快慢指针

fastslow 相遇后,此时,fast 继续向前走,head 向前走,最终 fasthead 相遇的结点即为入口。

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        if head==None: return
        fast,slow = head,head

        while True:
            if fast and fast.next:
                fast = fast.next.next
            else:
                return None
            slow = slow.next
            if fast == slow:
                break
        fast = head
        while fast!= slow:
            fast = fast.next
            slow = slow.next
        return fast
  • C++
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if (head==NULL) {
            return NULL;
        } 
        ListNode* fast = head;
        ListNode* slow = head;

        while (1){
            if (fast&&fast->next){
                fast = fast->next->next;
            }
            else{
                return NULL;
            }
            slow = slow->next;
            if (slow == fast){
                break;
            }
        }
        slow = head;
        while (slow != fast){
            slow = slow->next;
            fast = fast->next;
        }
        return fast;
    }
};