题目描述
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例
示例 1:
输入: head = [1,2,3,4]
输出: [2,1,4,3]
示例 2:
输入: head = []
输出: []
示例 3:
输入: head = [1]
输出: [1]
提示:
- 链表中节点的数目在范围 [0, 100] 内
- 0 <= Node.val <= 100
解题思路
- 递归实现
- 实现两两交换,如果节点数小于两个,直接返回
- 两个一组,把每组看成一个独立的小链表;
- 每组的尾节点(head.next),就是是反转后头节点newHead
- 然后让反转后的尾节点(原头节点),指向后面的反转完的节点;
- 最后让反转后的新的头节点 指向 原头节点
- 迭代实现
- 创建虚拟头节点ret,虚拟头节点指向原头节点;
- 找待反转区域的前一节点p,初始定义p = ret;
- p -> node1 -> node2 -> ....
- 第一个原链表节点node1, 第二个节点node2, 实现node1与node2反转;
- ret -> node2;虚拟指向node2
- node1 -> node2.next
- node2 -> node1
- 最后:p -> node2 -> node1 -> ....
- 第一组反转完成,
- 第二组要反转,先找待反转前一位,让 p = node1
javascript实现
/**
* 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 == null || head.next == null) return head;
// 两个一组,把每组看成一个独立的小链表;
// 每组的尾节点(head.next),就是是反转后头节点newHead
// 然后让反转后的尾节点(原头节点),指向后面的反转完的节点;
// 最后让反转后的新的头节点 指向 原头节点
// let newHead = head.next;
// head.next = swapPairs(newHead.next);
// newHead.next = head;
// return newHead
// 迭代实现
if(head == null || head.next == null) return head;
// 创建虚拟头节点ret,虚拟头节点指向原头节点
let ret = new ListNode(0, head), p = ret;
while(p.next && p.next.next){
let node1 = p.next, node2 = p.next.next; // 待反转的两个节点,
p.next = node2; // 让待反转区域的前一节点,指向待反转区域的最后一个节点
node1.next = node2.next;// 让node1指向 原node2指向的节点
node2.next = node1;
p = node1; // p 为下一组待反转的前一节点
}
return ret.next
};