返回

LeetCode-141. 环形链表(day32)

后端

问题
给定一个链表,判断它是否有环。如果是,则找到环形链表的入口节点。

解题思路:
这道题可以使用快慢指针法来解决。快指针每次移动两个节点,慢指针每次移动一个节点。如果快指针和慢指针相遇,则说明链表有环。

步骤:

  1. 将快指针和慢指针都指向链表头结点。
  2. 快指针每次移动两个节点,慢指针每次移动一个节点。
  3. 如果快指针和慢指针相遇,则说明链表有环。
  4. 将慢指针指向链表头结点,快指针保持不变。
  5. 快指针和慢指针同时每次移动一个节点,直到它们相遇。
  6. 相遇的节点即为环形链表的入口节点。

代码实现:

def has_cycle(head):
    """
    判断链表是否有环

    Args:
        head: 链表头结点

    Returns:
        True: 有环
        False: 无环
    """

    slow = head
    fast = head

    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next

        if slow == fast:
            return True

    return False


def find_cycle_entrance(head):
    """
    找到环形链表的入口节点

    Args:
        head: 链表头结点

    Returns:
        环形链表的入口节点
    """

    slow = head
    fast = head

    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next

        if slow == fast:
            break

    slow = head

    while slow != fast:
        slow = slow.next
        fast = fast.next

    return slow

时间复杂度:
快慢指针法的时间复杂度为 O(n),其中 n 为链表的长度。

空间复杂度:
快慢指针法只需要常数空间,因此空间复杂度为 O(1)。

示例:

# 创建一个环形链表
head = ListNode(1)
head.next = ListNode(2)
head.next.next = ListNode(3)
head.next.next.next = head

# 判断链表是否有环
has_cycle(head)  # True

# 找到环形链表的入口节点
find_cycle_entrance(head)  # ListNode(1)

总结:
LeetCode-141. 环形链表是一道经典的链表题目,难度为中等。这道题考察了我们对链表的理解以及算法设计的能力。快慢指针法是一种非常有效的方法,可以用来解决这类问题。

希望今天的分享对大家有所帮助。如果您有任何问题或建议,欢迎在评论区留言。