跳到主要内容

24. 两两交换链表中的节点

题目描述

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

示例 1

示例1

输入head = [1,2,3,4]

输出[2,1,4,3]

示例 2

输入head = []

输出[]

示例 3

输入head = [1]

输出[1]

提示

  • 链表中节点的数目在范围 [0, 100]
  • 0 <= Node.val <= 100

出处LeetCode

解法一:递归

思路

我们可以使用递归来交换链表中相邻的节点。我们定义一个递归函数 swap,函数的参数是两个节点 node1node2,分别表示要交换的两个节点。在递归函数中,我们首先判断 node1node2 是否为空,如果其中有一个为空,则返回另一个节点。然后,我们交换 node1node2 两个节点,即将 node1next 指针指向 node2next 节点,将 node2next 指针指向 node1。最后,我们返回 node2 节点。

实现

function swapPairs(head: ListNode | null): ListNode | null {
if (head === null || head.next === null) {
return head;
}

const node1 = head;
const node2 = head.next;

node1.next = swapPairs(node2.next);
node2.next = node1;

return node2;
}

复杂度分析

  • 时间复杂度:O(n)O(n),其中 nn 是链表的长度
  • 空间复杂度:O(n)O(n)

解法二:迭代

思路

我们也可以使用迭代来交换链表中相邻的节点。我们定义一个哑节点 dummy,然后定义一个指针 prev 指向哑节点。然后我们遍历链表,每次迭代时,我们将两个相邻的节点 node1node2 分别指向 prev.nextprev.next.next。然后,我们将 prev.next 指向 node2node1next 指针指向 node2next 节点,node2next 指针指向 node1。最后,我们将 prev 指针指向 node1,继续迭代。

实现

function swapPairs(head: ListNode | null): ListNode | null {
const dummy = new ListNode(0);
dummy.next = head;

let prev = dummy;

while (prev.next !== null && prev.next.next !== null) {
const node1 = prev.next;
const node2 = prev.next.next;

prev.next = node2;
node1.next = node2.next;
node2.next = node1;

prev = node1;
}

return dummy.next;
}

复杂度分析

  • 时间复杂度:O(n)O(n),其中 nn 是链表的长度
  • 空间复杂度:O(1)O(1)