Subject description:
Given a single linked list L: L 0 → L 1 → ... → L n-1 → L n,
Reorder: L 0 → L n → L 1 → L n-1 → L 2 → L n-2 → ...
It requires the use of in-place algorithm, and does not change the value of the node
E.g:
For a given single chain {1,2,3,4}, which is {1,4,2,3} reordered.
Problem-solving ideas:
1, the linked list into two parts, such as 1-> 2-> 3-> 4-> 5-> null, into l1: 1-> 2-> 3-> null, and l2: 4-> 5-> null
2, the second linked list reversed, so l2: 5-> 4-> null
3, the two merged list
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public void reorderList(ListNode head) {
//当链表为空,或只有1个2个Node时,不需要反转
if (head == null || head.next == null || head.next.next == null)
return;
ListNode slow = head;
ListNode fast = head;
//最终slow指向的位置是reorder之后的最后一个Node
while(fast != null && fast.next != null){
slow = slow.next;
fast = fast.next.next;
}
//slow不可能是Null,end2也不会是Null
//end2指向l2的end node
ListNode end2 = slow.next;
//ppre指向要反转的node的前一个node
ListNode ppre = end2;
//p指向要反转的node
ListNode p = ppre.next;
//pnext指向要反转的node的下一个node,也就是下一个要反转的node
ListNode pnext = null;
//p指向null时,反转结束
while(p != null){
pnext = p.next;
p.next = ppre;
ppre = p;
p = pnext;
}
//反转结束,ppre指向l2的start node
ListNode start2 = ppre;
//将两个链表分离,使各自的end node指向null
end2.next = null;
slow.next = null;
//得到了2个链表l1和l2
ListNode l1 = head;
ListNode l2 = start2;
//为连接l1和l2所用,在改变node.next前要记录之前的node.next
ListNode l1next = null;
ListNode l2next = null;
//合并链表
while(l1 != null && l2 != null){
l1next = l1.next;
l2next = l2.next;
l1.next = l2;
l1 = l1next;
l2.next = l1;
l2 = l2next;
}
}
}