Reorder List
You are given the head of a singly linked-list. The list can be represented as:
L0 → L1 → … → Ln - 1 → Ln
Reorder the list to be on the following form:
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
You may not modify the values in the list's nodes. Only nodes themselves may be changed.
Example 1:
Input: head = [1,2,3,4]
Output: [1,4,2,3]
Example 2:
Input: head = [1,2,3,4,5]
Output: [1,5,2,4,3]
Solution:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
void reorderList(ListNode* head) {
int cnt = 0 ;
ListNode *slow = head, *fast = head ;
while( fast && fast -> next )
{
cnt ++ ;
slow = slow -> next ;
fast = fast -> next -> next ;
}
ListNode *pre = nullptr, *current = slow, *post = nullptr ;
while( current )
{
post = current -> next ;
current -> next = pre ;
pre = current ;
current = post ;
}
ListNode *temp = head -> next ;
while( pre -> next )
{
head -> next = pre ;
head = pre ;
pre = pre -> next ;
head -> next = temp ;
head = temp ;
temp = temp -> next ;
}
}
};
1) We can divide the linked list into two parts:
while( fast && fast -> next )
{
cnt ++ ;
slow = slow -> next ;
fast = fast -> next -> next ;
}
Like this way -
head pointer: [1,2,3,4,5]
slow pointer: [3,4,5]
2) Reverse the second part
ListNode *pre = nullptr, *current = slow, *post = nullptr ;
while( current )
{
post = current -> next ;
current -> next = pre ;
pre = current ;
current = post ;
}
This Happens - [3,4,5] => [5,4,3]
head pointer becomes: [1,2,3] as link with next part broken
3) Finally, Link both part of the linked list
ListNode *temp = head -> next ;
while( pre -> next )
{
head -> next = pre ;
head = pre ;
pre = pre -> next ;
head -> next = temp ;
head = temp ;
temp = temp -> next ;
}
This Happens - [1,2,3] [5,4,3]
[1,5]
[2,4]
[3]