原题
链表中等2 种解法

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

不修改节点值,将单链表中每两个相邻节点交换。

#链表#递归#迭代

原题

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

示例 1:

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

示例 2:

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

示例 3:

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

提示:

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

查看原题

解题主线

  1. 哨兵节点让首对节点的交换与后续节点对使用同一套重连逻辑。
  2. 递归中第二个节点成为当前段新头,第一个节点连接已交换完成的后缀。

解法 1:迭代重连

让 previous 指向每一对节点的前驱,交换后移动到该对的新尾部。

  • 时间复杂度: O(n)

  • 空间复杂度: O(1)

JAVA
final class ListNode {
    int val;
    ListNode next;

    ListNode(int val) {
        this.val = val;
    }

    ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}

final class Solution {
    public ListNode swapPairs(ListNode head) {
        // 哨兵统一首对节点与后续节点对的前驱重连逻辑
        ListNode dummy = new ListNode(0, head);
        ListNode previous = dummy;
        // 仅在后方至少还有两个节点时执行交换
        while (previous.next != null && previous.next.next != null) {
            ListNode first = previous.next;
            ListNode second = first.next;
            // 先接回后缀,再反转当前二元组,避免链表断裂
            first.next = second.next;
            second.next = first;
            previous.next = second;
            // first 已成为当前二元组尾部,也是下一轮的前驱
            previous = first;
        }
        return dummy.next;
    }
}

解法 2:递归交换

先递归交换第二个节点之后的链表,再翻转当前两个节点的连接。

  • 时间复杂度: O(n)

  • 空间复杂度: O(n),递归栈

JAVA
final class ListNode {
    int val;
    ListNode next;

    ListNode(int val) {
        this.val = val;
    }

    ListNode(int val, ListNode next) {
        this.val = val;
        this.next = next;
    }
}

final class Solution {
    public ListNode swapPairs(ListNode head) {
        // 不足两个节点时无法成对交换,直接保留当前后缀
        if (head == null || head.next == null) return head;
        ListNode second = head.next;
        // 原首节点连接已经完成两两交换的剩余链表
        head.next = swapPairs(second.next);
        // 第二个节点成为当前二元组的新头
        second.next = head;
        return second;
    }
}

边界与易错点

  • 重连前先保存两个节点引用,避免修改 next 后丢失后缀。
  • 奇数长度链表的最后一个节点保持原位。

整理来源

由旧仓库源码复核、去重并整理;展示代码已按 Java 21 语义修正明显问题。

  • medium/Q024_swapPairs.java