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

难度:🟡 中等

标签链表递归

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

题目描述

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

示例 1:

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

示例 2:

输入:head = []
输出:[]

示例 3:

输入:head = [1]
输出:[1]

解题思路

核心思想

本题的核心是在原地两两交换链表中的相邻节点。要交换一对节点 node1node2,我们不仅需要改变它们自身的 next 指针,还需要改变 node1 的前驱节点的 next 指针,使其指向交换后的 node2

思路选择

迭代法 + 虚拟头节点(Dummy Head) 是解决此问题的标准最优思路。

  • 虚拟头节点:我们创建一个 dummy 节点,其 next 指向原始的 head。这可以极大地简化边界情况的处理,尤其是交换头两个节点时,我们无需编写特殊逻辑。

  • 指针迭代:我们使用一个指针 prev,它始终指向 待交换的一对节点的前一个节点。通过这个 prev 指针,我们可以方便地进行交换操作。

关键步骤

  1. 创建虚拟头节点const dummyHead = new ListNode(0, head)

  2. 初始化指针:创建一个指针 prev = dummyHead

  3. 循环遍历:当 prev 后面至少还有两个节点时(即 prev.nextprev.next.next 都不为空),持续循环。

  4. 定义待交换节点: a. node1 = prev.next b. node2 = prev.next.next

  5. 执行交换: a. prev.next = node2 (前驱节点指向第二个节点) b. node1.next = node2.next (第一个节点指向第三个节点) c. node2.next = node1 (第二个节点指向第一个节点)

  6. 移动 prev 指针:完成交换后,node1 已经成为了这对节点的第二个。我们将 prev 移动到 node1 的位置,为下一轮交换做准备。

  7. 返回结果:循环结束后,返回 dummyHead.next,它指向新链表的头节点。

代码实现

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 * this.val = (val===undefined ? 0 : val)
 * this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var swapPairs = function(head) {
    const dummyHead = new ListNode(0, head);
    let prev = dummyHead;

    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 指针到下一对节点的前面
        prev = node1;
    }

    return dummyHead.next;
};

复杂度分析

  • 时间复杂度O(n) 其中 n 是链表的长度。我们只需要对链表进行一次完整的遍历。

  • 空间复杂度O(1) 我们只使用了常数个额外变量作为指针,操作是在原链表上进行的,空间消耗是恒定的。

相关题目

总结

本题是链表指针操作的经典练习题。其核心在于通过一个虚拟头节点和一个前驱指针,来清晰、安全地完成节点的重新链接。理解指针在交换过程中的变化是掌握此题的关键。

Copyright © Jun 2025 all right reserved,powered by Gitbook该文件修订时间: 2025-07-03 17:35:08

results matching ""

    No results matching ""

    results matching ""

      No results matching ""