返回

代码实现

/**
 * 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) {
    if (!head || !head.next) return head;
    const dummy = new ListNode(0, head); // 虚拟头节点
    let prev = dummy;
    while (prev.next && prev.next.next) {
        const curr = prev.next;          // 第 1 个节点
        const next = curr.next;          // 第 2 个节点

        // 翻转这一对
        curr.next = next.next;
        next.next = curr;
        prev.next = next;

        // 前进两步,准备处理下一对
        prev = curr;
    }

    return dummy.next;
};

思路解析:

初始状态(图 1)

dummy ─► 1 ─► 2 ─► 3 ─► 4 ─► null
  ↑      ↑    ↑
 prev  curr next

此时

  • prev = dummy
  • curr = prev.next(节点 1)
  • next = curr.next(节点 2)

第一次翻转:交换节点 1 和 2(图 2)

执行 3 次指针重接:

  1. curr.next = next.next  // 1 指向 3
  2. next.next = curr    // 2 指向 1
  3. prev.next = next    // dummy 指向 2
dummy ─► 2 ─► 1 ─► 3 ─► 4 ─► null
         ↑    ↑    ↑
        prev curr next

指针整体前移 2 步(图 3)

  • prev = curr  // 现在 prev 指向节点 1
  • 新的 curr = prev.next(节点 3)
  • 新的 next = curr.next(节点 4)
dummy ─► 2 ─► 1 ─► 3 ─► 4 ─► null
              ↑    ↑    ↑
             prev curr next

接下来重复同样的 3 步把 3 和 4 交换即可。当 prev.nextprev.next.nextnull 时循环结束,最终链表变成:

2 → 1 → 4 → 3

对照代码回顾

const curr = prev.next;      // 第 1 个节点
const next = curr.next;      // 第 2 个节点

curr.next = next.next;       // ①
next.next = curr;            // ②
prev.next = next;            // ③

prev = curr;                 // ④ 整体前移两步