1.Description
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}.
2.Analysis
To solve this problem, we have two attention Note.
A. The pointer exchange order.
Assume List {1 2 3 4 5}
pointer p1 L0 1
p2 Ln 5
p3 Ln-1 4
the reorder should be 1 5 2 3 4
the opertation should p3 = NULL;
p2.next = p1.next;
p1.next = p2;
draw a picture about the order can help greatly.
B. Time
We draw the conclusion we need to search the List n/2 times for the reorder the computation complexity should be O(n^2)
This indeed waste much time.
For the reorder List, L0→Ln→L1→Ln-1→L2→Ln-2→…
We need the location of Ln, Ln-1, Ln-2.....This means if we know the their location prior to reorder, we don't need to search the list again and again.
Solution:
Search the List and record their Location.
NOTE: This can be treated as the reducing the operation time at the expense of using more space.
3, CODE:
Time Exceed Code:
if(head == NULL || head->next == NULL)
return;
ListNode *p1, *p2, *p3;
std::vector<ListNode*> location;
std::vector<ListNode*>::iterator it;
p1 = head;
while(p1 != NULL)
{
location.insert(location.begin(), p1);
p1 = p1->next;
}
p1 = head;
it = location.begin();
p2 = *(it++);
p3 = *(it);
while(it!= location.end() && p2 != p1 && p2 != p1->next)
{
p3->next = NULL;
p2->next = p1->next;
p1->next = p2;
p1 = p2->next;
p2 = *(it++);
p3 = *(it);
}
AC code
if(head == NULL || head->next == NULL)
return;
ListNode *p1, *p2, *p3;
std::vector<ListNode*> location;
std::vector<ListNode*>::iterator it;
p1 = head;
while(p1 != NULL)
{
location.insert(location.begin(), p1);
p1 = p1->next;
}
p1 = head;
it = location.begin();
p2 = *(it++);
p3 = *(it);
while(it!= location.end() && p2 != p1 && p2 != p1->next)
{
p3->next = NULL;
p2->next = p1->next;
p1->next = p2;
p1 = p2->next;
p2 = *(it++);
p3 = *(it);
}