Swift 找到链表中环的入口节点

102 阅读1分钟

在 Swift 中找到链表中环的入口节点,可以使用快慢指针的方法。当快慢指针相遇时,将其中一个指针指向头结点(或者从头开始移动相同步数),然后两个指针同时以相同的速度移动,再次相遇的节点就是环的入口节点。下面是一个基本的实现:

class ListNode {
    var val: Int
    var next: ListNode?

    init(_ val: Int) {
        self.val = val
    }
}

func detectCycle(_ head: ListNode?) -> ListNode? {
    var slow = head
    var fast = head?.next

    while fast != nil && fast?.next != nil {
        if slow === fast {
            // 相遇时,将一个指针重新指向头结点
            slow = head
            // 两个指针再次以相同速度移动,直到相遇
            while slow !== fast {
                slow = slow?.next
                fast = fast?.next
            }
            return slow
        }
        slow = slow?.next
        fast = fast?.next?.next
    }
    return nil
}

上述代码中,定义了一个 ListNode 类表示链表的每一个节点。detectCycle 方法用于返回链表中环的入口节点,该方法重载了一个参数:链表的头节点。

在实现中,我们定义了两个指针 slowfast 分别指向链表的头节点和第二个节点,然后通过循环迭代的方式找到快慢指针相遇的节点。当快慢指针相遇时,将其中一个指针重新指向头结点,然后两个指针同时以相同的速度移动,直到它们再次相遇。此时的节点就是环的入口节点。

需要注意的是,由于 Swift 是一门强类型语言,因此不能直接将两个对象进行比较。在上述代码中,我们使用了 === 运算符来判断两个指针是否指向同一个对象。