题目描述
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 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 headlet dummyHead = new ListNode(0, head)let cur = dummyHeadwhile (cur.next != null && cur.next.next != null) {let temp = cur.nextlet temp1 = cur.next.next.nextcur.next = cur.next.nextcur.next.next = temptemp.next = temp1cur = cur.next.next}return dummyHead.next
};