返回

新链表:旧链表扣子,新链表穿针引线

前端

处理链表的本质,是处理链表结点之间的指针关系。

假设有一个现有的链表,我们要创建一个新的链表,同时包含原链表的所有元素,但要求新链表中不包含任何重复元素。

比如,现有链表为:[1, 2, 3, 4, 5, 1, 2, 3],我们需要创建一个新链表,包含元素[1, 2, 3, 4, 5],且不包含任何重复元素。

处理这个问题的关键,是记住链表本质上是由结点和指针组成的。每个结点都包含数据和指向下一个结点的指针。因此,我们可以将结点看作是扣子,新链表的指针像线一样,将扣子穿起来。

因此,我们可以按照以下步骤创建一个新链表:

  1. 首先,创建一个新链表的头结点。

  2. 然后,遍历旧链表中的每个结点。

  3. 如果旧链表中的结点没有重复,则将其添加到新链表的末尾。

  4. 否则,跳过该结点。

这样做的好处是,我们不需要额外的数据结构来存储旧链表中的结点,因为我们可以直接使用新链表中的结点。

这种方法的时间复杂度是O(n),其中n是链表中的结点数量。这是因为我们需要遍历旧链表中的每个结点,并且在将结点添加到新链表时,我们需要搜索新链表中的所有结点以确保没有重复。

这种方法的空间复杂度是O(1),因为我们不需要额外的数据结构来存储旧链表中的结点。

虽然看着两层循环,但其实,每个节点只遍历一次,所以时间复杂度是 O(n),空间复杂度是 O(1). 这里,重复的节点本身也会删除。

这种方法非常简单且高效,因此非常适合处理链表。

def remove_duplicates(head):
  """
  Removes duplicates from a linked list.

  Args:
    head: The head of the linked list.

  Returns:
    The head of the linked list with duplicates removed.
  """

  # Create a new linked list to store the unique elements.
  new_head = ListNode(None)

  # Keep track of the current node in the new linked list.
  current = new_head

  # Iterate over the old linked list.
  while head:
    # If the current element is not in the new linked list, add it.
    if head.val not in new_head:
      current.next = head
      current = current.next

    # Move to the next element in the old linked list.
    head = head.next

  # Return the head of the new linked list.
  return new_head.next