24. 两两交换链表中的节点
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例2:
输入:head = []
输出:[]
示例3:
输入:head = [1]
输出:[1]
算法思路:
定义四个指针,p,pre,t,res,让 t 每次指向 p 的 后 一个,pre 指向 p 的前一个,res 用来记住新链表的头,通过 flag 标志实现 让 res 只记录第一次 t 的值(因为 t 会变)。如果 t 为空,说明到尾部,无法交换,直接结束。t.next = pre;
让 t 下一个指向其前一个,而 pre 的 下一个指向分两种情况
- p 为 null,直接为 null
- p 不为 null 时分两种情况(此时总节点数大于 1):
- 总结点数为奇数 ( p.next == null ) 让 pre 下一个指向 p
- 总结点数为偶数 ( p.next != null ) 让 pre下一个指向 p.next
代码实现:
public class Q0024SwapNodesInPairs {
public static void main(String[] args) {
Solution solution = new Q0024SwapNodesInPairs().new Solution();
int[] nums = {1,2,3,4,5,6,7};
ListNode listNode = ListNode.create(nums);
ListNode.print(listNode);
ListNode listNode1 = solution.swapPairs(listNode);
ListNode.print(listNode1);
}
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode p = head, pre, t, res = null;
// 用来记录新链表的头
boolean flag = true;
while (p != null) {
t = p.next;
pre = p;
// 只记录为第一次
if (flag) res = t;
if (t == null) break;
flag = false;
p = t.next;
t.next = pre;
// p 不为 null 时分两种情况(节点数大于 1):
// 1.结点数为奇数 (p.next == null) 让 pre下一个指向 p
// 2.结点数为偶数 (p.next != null) 让 pre下一个指向 p.next
pre.next = p == null ? null : p.next == null ? p : p.next;
}
// 如果 res 为空说明只有一个结点直接返回原链表
return res == null ? head : res;
}
}
}