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}
.
常规版本:遍历链表的方式,事实证明,遍历永远不是最好的!
void reorderList(ListNode* head) {//递归、循环效果应该差不多 ListNode* p=head; if(head==NULL || head->next==NULL) return; ListNode* currentNode=p; ListNode* nextNode=p->next; ListNode* newNextNode=nextNode; while(nextNode && nextNode->next) { ListNode* preNewNextNode=currentNode; ListNode* prePreNewNextNode=currentNode; while(newNextNode->next) { preNewNextNode=preNewNextNode->next; newNextNode=newNextNode->next; } prePreNewNextNode->next=NULL; preNewNextNode->next=NULL; currentNode->next=newNextNode; newNextNode->next=nextNode; currentNode=nextNode; nextNode=currentNode->next; newNextNode=nextNode; } }
反转子链表版本:用两个指针,一快一慢遍历整个链表,直到较快的链表到达末尾,慢指针刚好到达中点,然后断开链表。把后段链表反转,再逐个插入。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: ListNode* reverseList(ListNode* head) { if(!head) return head; ListNode* p=head; ListNode* q=p->next; if(!q) return head; ListNode* k=q->next; p->next=NULL; while(k) { q->next=p; p=q; q=k; k=k->next; } q->next=p; return q;//返回头结点 } void reorderList(ListNode* head) { if(head==NULL || head->next==NULL) return; ListNode* p=head; ListNode* fast=p; ListNode* slow=p; while(fast && fast->next) { fast=fast->next->next; slow=slow->next; } ListNode* subHead=slow->next; slow->next=NULL; subHead=reverseList(subHead); ListNode* p2=subHead; while(p2!=NULL) { ListNode* tmp1=p->next; ListNode* tmp2=p2->next; p->next=p2; p2->next=tmp1; p2=tmp2; p=tmp1; } } };