Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
You must do this in-place without altering the nodes' values.
For example,
Given {1,2,3,4}, reorder it to {1,4,2,3}.
Analysis:
One straightforward middle step of such reordering is:
{1,2,3,4,5,6} --> {1,2,3,6,5,4}
--> {1,6,2,5,3,4}
{1,2,3,4,5,6,7}---> {1,2,3,4,7,6,5}
---> {1,7,2,6,3,5,4}
By reversing the last half part of the linked list, we do not need to worried about the "parent" pointer anymore. The
final step is just insert the each element in the last half part into the first part (every two element).
So the algorithm implemented below can be summarized as:
Step 1 Find the middle pointer of the linked list (you can use the slow/fast pointers)
Step 2 Reverse the second part of the linked list (from middle->next to the end)
Step 3 Do the reordering. (inset every element in the second part in between the elements in the first part)
java
public void reorderList(ListNode head) {
if(head==null || head.next == null|| head.next.next == null) return;
ListNode slow = head;
ListNode fast = head;
while(fast!=null&& fast.next!=null){
slow = slow.next;
fast = fast.next.next;
}
//slow is in the middle, reverse slow.next to end
fast = slow.next;
slow.next = null;
while(fast!=null){
ListNode temp = fast.next;
fast.next = slow;
slow = fast;
fast = temp;
}//merge two list
ListNode first = head;
ListNode second = slow;
while(first!=null && first.next!=second && first!=second){
ListNode temp = second.next;
second.next = first.next;
first.next = second;
first = second.next;
second = temp;
}
}c++
void reorderList(ListNode *head) {
if(head == NULL || head->next == NULL) return;
//find half node
ListNode *slow = head;
ListNode *fast = head;
while(true){
fast = fast->next;
if(fast == NULL)
break;
fast = fast->next;
if(fast == NULL)
break;
slow = slow->next;
}
//resever post half list
ListNode *cur = slow;
ListNode *pre = slow->next;
cur->next = NULL;
while(pre!=NULL){
ListNode *temp = pre->next;
pre->next = cur;
cur = pre;
pre = temp;
}
// merge two list
ListNode *first = head;
ListNode *second = cur;
while(first != second && first != NULL && second != NULL){
ListNode *temp = second->next;
second->next = first->next;
first->next = second;
first = second->next;
second = temp;
}
}

本文介绍了一种在不改变节点值的情况下,对单链表进行特定重排序的算法。通过三个步骤实现:寻找链表中点,反转后半部分链表,最后将反转后的链表与前半部分交错合并。
130

被折叠的 条评论
为什么被折叠?



