Problem 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{1,4,2,3}
.
Analysis: as required, the elements of the linked list are exchanged. The first method is to directly traverse the linked list and store all node pointers in the vector. Then, the linked list can be re-built at one end. The Code is as follows:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: void reorderList(ListNode *head) { ListNode *p=head; int length,i=1,tag=0; vector<ListNode* > array; while(p) { array.push_back(p); p=p->next; } p=head; if(array.size()<3) return; length=array.size()-1; while(tag<array.size()/2) { p->next=array[length--]; p=p->next; p->next=array[i++]; p=p->next; tag++; } p->next=NULL; }};
The second method is to find the intermediate node of the linked list, divide the Linked List into two halves, transpose the second half, and merge the two parts as follows:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: void reorderList(ListNode *head) { if (!head){return;} if (head->next==NULL){return;} ListNode *p=head; ListNode *q=head; //find the midddle pointer while (q->next && q->next->next){ p=p->next; q=q->next->next; } //now p is middle pointer //reverse p->next to end q = p->next; while (q->next){ ListNode* tmp = p->next; p->next = q->next; q->next = q->next->next; p->next->next = tmp; } //reorder q = head; while (p!=q && p->next){ ListNode* tmp = q->next; q->next = p->next; p->next = p->next->next; q->next->next = tmp; q=q->next->next; } return; }};