这个题目思路就是:
- 先把链表分成两个长度相等(奇数的时候后半部分少一个)的子链表
- 然后将后面的链表进行反转
- 最后将两个链表合并,后面的链表总是插入到前面链表的后面
public void reorderList(ListNode head) {
if (head == null || head.next == null) //有0个或1个结点,直接返回
return;
ListNode p1 = head.next, p2 = p1.next; //使用快慢指针找到中间节点
if (p2 == null) //说明有两个结点,也直接返回
return;
while(p2 != null && p2.next != null) { //快慢指针向后找
p1 = p1.next;
p2 = p2.next.next;
}
//此时p1指向的是中间节点,然后断成p1和p2两个链表
p2 = p1.next;
p1.next = null; //这个地方把链表断成了两个
//倒置p2
p2 = reverse(p2);
p1 = head;
while(p2 != null) {
//先记录p2的下一个
ListNode next = p2.next;
//将p2插入到p1中
p2.next = p1.next;
p1.next = p2;
//更新p1和p2
p1 = p2.next;
p2 = next;
}
}
private ListNode reverse(ListNode head) {
if (head == null || head.next == null)
return head;
ListNode temp = head.next;//保存下一个节点
ListNode newHead = reverse(head.next);//整体思维,宏观语义
temp.next = head;//连上头与递归部分
head.next = null;//调整尾部
return newHead;//返回头节点
}