前言
这题自己第一想法是K个一组翻转链表,K为2。
然后仔细想了下,没必要。如果用上述方法真的是简单问题复杂化了。
直接三个指针(分别指向已交换尾、待交换头、待交换尾) + 迭代就可以搞定。
一、题目描述
详细描述请看:leetcode的题目描述
大致描述:
- 一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
- 示例:
二、解题
2.1 思路
- 空链表、只有一个节点的链表不需要交换
- 虚拟头节点:由于需要操作头节点的前一个节点,故需要虚头
- 迭代,迭代继续的条件:为交换节点数大于2
- 每次交换怎么交换? 看代码吧,其实就是头插法。
将删掉的尾插到已完成交换的尾这句话算是交换重点。
2.2 代码
/**
* 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}
*/
const swapPairs = function (head) {
// 空链表 、 只有一个节点的链表不需要交换
if(head === null || head.next === null) return head
// 虚拟头节点,需要操作头节点的前一个节点
let dummy = new ListNode(-1, head)
// 该指针每轮迭代都指向完成交换的尾部
let pre = dummy
// 迭代继续的条件,未交换节点数超过2
while(pre.next && pre.next.next) {
// first指向第一个节点、second指向第二个节点(这里的节点指即将两两交换的节点)
let first = pre.next, second = pre.next.next
// 接下来就是交换过程,三部走:second删、插
// 删second
first.next = second.next
// 插second到pre后
second.next = first
pre.next = second
// 以上已经完成交换, pre需要指向已完成交换的尾部
pre = first
}
return dummy.next
}