题目描述
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 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 完成后的后两位。
下图来自代码随想录的题解
现在顺序问题总算说完了,下一个难点是节点会丢失,这里我使用了 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
};