【数据结构与算法】力扣 24. 两两交换链表中的节点

62 阅读2分钟

题目描述

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

示例 1:

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

示例 2:

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

示例 3:

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

提示:

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

分析解答

这道题和链表的逆置并不同。它需要每两个节点和他们后面的下一个(也就是第三个节点)发生关系(指向),所以可以考虑引入一个虚拟头节点进行操作。

所以现在就成了 dummyHead,cur,cur.next 这三个节点的指向不断改变。但此时又有了另一个难点,操作的先后顺序。

先以 1 -> 2 -> 3 为例,操作过后为 2 -> 1 -> 3,而 cur 先指向 1,然后指向了 2,之后还会指向 1,此时的 1 是指第一次操作 cur 完成后的后两位

下图来自代码随想录的题解

image.png

image.png

现在顺序问题总算说完了,下一个难点是节点会丢失,这里我使用了 temp 和 temp1 来保存节点,以避免这个问题。实际上这里的 dummyHead 也只是为了保存头节点,防止丢失。

最后就是考虑边界了,cur.next != null && cur.next.next != null ,想必这个在上面问题的衬托下已经变得非常简单了。

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
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 == null || head.next == null) return head
    let dummyHead = new ListNode(0, head)
    let cur = dummyHead
    while (cur.next != null && cur.next.next != null) {
        let temp = cur.next
        let temp1 = cur.next.next.next
        cur.next = cur.next.next
        cur.next.next = temp
        temp.next = temp1
        cur = cur.next.next
    }
    return dummyHead.next
};

思路拓展