返回

LeetCode 1721 解题攻略:交换链表中的节点

前端

导言

数据结构和算法在软件开发中至关重要,而链表是其中最基本也是最常用的结构之一。链表操作是数据结构面试中的常见问题,掌握它们对于任何有抱负的工程师都是必不可少的。在这篇文章中,我们将深入探讨 LeetCode 1721 问题,该问题要求交换链表中的两个节点,并提供一种清晰、分步的解决方案。

理解问题

给定一个链表的头节点 head 和两个整数 ab1721. 交换链表中的节点 问题要求我们交换链表中值为 ab 的两个节点。为了清楚起见,让我们举一个例子:

输入:head = [1,2,3,4,5], a = 2, b = 4
输出:[1,4,3,2,5]

在这个例子中,链表的值为 a = 2b = 4 的节点分别是 24。交换它们之后,链表变为 [1,4,3,2,5]

分步解决方案

为了解决这个问题,我们可以采用以下分步策略:

1. 找到节点

首先,我们需要找到值为 ab 的节点。我们可以遍历链表,并将每个节点的值与 ab 进行比较。找到节点后,将它们存储在变量 nodeAnodeB 中。

2. 处理特殊情况

在这个步骤中,我们需要处理两种特殊情况:

  • nodeAnodeBnull:如果任一节点为 null,则无法进行交换。在这种情况下,我们返回原始链表。
  • nodeAnodeB 为相邻节点:如果 nodeAnodeB 是相邻节点,则我们可以直接交换它们的指针。

3. 交换节点

对于一般情况,我们需要交换 nodeAnodeB 的指针,以实现值的交换。我们可以通过以下步骤来完成:

  • nodeA 的下一个指针指向 nodeB 的下一个指针。
  • nodeB 的下一个指针指向 nodeA
  • nodeAnodeB 的前驱指针更新为彼此。

时间复杂度

该算法的时间复杂度为 O(n),其中 n 是链表中的节点数。这是因为我们需要遍历链表以找到节点 ab

代码示例

def swapNodes(head, a, b):
  """
  交换链表中值为 a 和 b 的两个节点。

  参数:
    head: 链表的头节点
    a: 第一个节点的值
    b: 第二个节点的值

  返回:
    交换节点后的链表头节点
  """

  # 找到节点 a 和 b
  nodeA = None
  nodeB = None
  curr = head
  while curr:
    if curr.val == a:
      nodeA = curr
    elif curr.val == b:
      nodeB = curr
    curr = curr.next

  # 处理特殊情况
  if not nodeA or not nodeB:
    return head
  if nodeA.next == nodeB:
    nodeA.next, nodeB.next = nodeB.next, nodeA
    return head

  # 交换节点
  prevA = nodeA.prev
  prevB = nodeB.prev
  nodeA.next, nodeB.next = nodeB.next, nodeA.next
  nodeA.prev, nodeB.prev = prevB, prevA
  if prevA:
    prevA.next = nodeB
  if prevB:
    prevB.next = nodeA

  # 返回交换节点后的链表
  return head

结论

通过遵循这些步骤,我们可以有效地解决 LeetCode 1721 问题并交换链表中的两个节点。理解这种技术对于解决涉及链表操作的各种问题至关重要。通过练习和对数据结构的深入理解,你可以掌握链表操作并成为一名更有能力的程序员。