package leecode;
/**
* 143. 重排链表
*
* 给定一个单链表 L 的头节点 head ,单链表 L 表示为:
* L0 → L1 → … → Ln - 1 → Ln
* 请将其重新排列后变为:
* L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
* (说人话就是说把最后一个插到第一个后面,把倒数第二个插到第二个后面 以此类推...)
*
* @author TANG
* @date 2021/12/22
*/
public class ReorderList {
/**
* 第一次遍历找到链表中间的位置
* 拆分成两个链表
* 第二次遍历 翻转后半链表
*
* 第三次遍历 两个链表顺序插入
*
* @param head
*/
public void reorderList(ListNode head) {
//第一步 快慢指针找到链表中点
ListNode slow = head;
ListNode fast = head;
//快指针走两步 慢指针走一步 最后慢指针作为中点
while(fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
//第二步
//翻转新链表
ListNode newList = slow.next;
slow.next = null;
//temp代表下一个要反转的元素
if(newList == null) {
return;
}
ListNode temp = newList.next;
newList.next = null;
while(temp != null) {
ListNode tempNext = temp.next;
temp.next = newList;
newList = temp;
temp = tempNext;
}
//翻转后起始元素是newList
//第三步 合并插入
while(head != null && newList != null) {
ListNode headNext = head.next;
ListNode newNext = newList.next;
head.next = newList;
newList.next = headNext;
head = headNext;
newList = newNext;
}
}
}