题目描述
给定一个单链表 L 的头节点 head ,单链表 L 表示为:
L0 → L1 → … → Ln-1 → Ln
请将其重新排列后变为:
L0 → Ln → L1 → Ln-1 → L2 → Ln-2 → …
不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
提示:
- 链表的长度范围为 [1, 5 * 104]
- 1 <= node.val <= 1000
题解
寻找链表中点 + 链表逆序 + 合并链表
- 利用快慢指针寻找到链表在中点,断开
- 把后面的链表逆序
- 然后两个链表交替合并,详见代码注释
class Solution {
public void reorderList(ListNode head) {
//快慢指针寻找链表中点,快的一次走两格,慢的一次走一格
ListNode fast = head, slow = head;
while (fast.next != null && fast.next.next != null){
fast = fast.next.next;
slow = slow.next;
}
//断开成两个链表,新建dummy节点,作为反转链表的哑节点
ListNode dummy = new ListNode(), headb = slow.next;
slow.next = null;
//反转后面的链表
while (headb != null){
ListNode cur = headb;
headb = headb.next;
cur.next = dummy.next;
dummy.next = cur;
}
dummy = dummy.next;
//此时head为前面的链表,dummy为后面反转过后的链表
//把dummy的链表,每间隔一个插入到head的链表中
while (dummy != null){
ListNode cur = dummy;
dummy = dummy.next;
cur.next = head.next;
head.next = cur;
head = head.next.next;
}
}
}