跳到主要内容

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,函数的参数是两个节点 node1 和 node2,分别表示要交换的两个节点。在递归函数中,我们首先判断 node1 和 node2 是否为空,如果其中有一个为空,则返回另一个节点。然后,我们交换 node1 和 node2 两个节点,即将 node1 的 next 指针指向 node2 的 next 节点,将 node2 的 next 指针指向 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 指向哑节点。然后我们遍历链表,每次迭代时,我们将两个相邻的节点 node1 和 node2 分别指向 prev.next 和 prev.next.next。然后,我们将 prev.next 指向 node2,node1 的 next 指针指向 node2 的 next 节点,node2 的 next 指针指向 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)