1. 题目描述
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换
- 示例 1
输入:head = [1,2,3,4]
输出:[2,1,4,3]
- 示例 2
输入:head = []
输出:[]
- 示例 3
输入:head = [1]
输出:[1]
2. 解题思路
- head 和 head.next 两个结点, 交换顺序由之前的 head -> head.next, 变更为 head.next -> head, 示例 1 中的 2 -> 1
- 每次遍历将 head 赋值 current, 用于下次遍历时, 将 current.next -> head.next, 示例 1 中的 1 -> 4
- 每次遍历最后需要将 head.next.next 赋值给 head, 用于下次遍历
- 需要考虑奇数个结点的场景, 最后一个结点无法交换顺序, 需要将 current.next = head, 例如 1 -> 2 -> 3 -> 4 -> 5 中的 5 , 最后交换完顺序后 2 -> 1 -> 4 -> 3 -> 5
- 如果只有一个结点, 提前判断, 不用参与遍历
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
if (null == head || null == head.next) {
return head;
}
ListNode result = new ListNode(-999, head);
ListNode current = result;
// 判断当前 和 next 结点不为空
while (null != head && null != head.next) {
// 将 current.next 指向 next
current.next = head.next;
// 将 next 的 next 结点保存, 最后要指向 head
ListNode nextNode = head.next.next;
// 将 next 的 next 指向 head, 由 next 指向 head 交换顺序
head.next.next = head;
// 将 head 指向 next 断开
head.next = null;
// 将 head 结点保存到下次遍历, head结点在下次遍历时, 将指向 next 的 next.next
current = head;
// 将 next 的 next 结点赋值给 head, 用于下次遍历
head = nextNode;
}
if (null != head) {
current.next = head;
}
return result.next;
}
}