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}
.
1.Stack,O(n) time,O(n)space
遍历链表,存入栈中
依次弹出栈中元素,插入到原链表中
最后将之后多余的链表置为NULL
/**
* 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* phead = head;
if(phead==NULL) return;
stack<ListNode*> L;
int length = 0;
while(phead!=NULL){
L.push(phead);
phead = phead->next;
length++;
}
ListNode* cur = head;
for(int i=0; i<(length-1)/2;i++){
ListNode* next = cur->next;
ListNode* insertItem = L.top();
L.pop();
cur->next =insertItem;
insertItem->next = next;
cur = next;
}
length%2==0?cur->next->next=NULL:cur->next = NULL;
}
};
2.想法儿,节约space,定义两个指针p1,p2,一个的速度是另一个的两倍,当p2到达末尾时,p1将链表分为两部分,将后一部分reverse,然后将两个链表merge,得到最终结果
/**
* 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) {//split as two lists and merge two,not use stack,but two pointers,
if(head==NULL||head->next==NULL) return;
ListNode* p1 = head;
ListNode* p2 = head;
while(p2!=NULL && p2->next!=NULL){//O(n) time.
p1 = p1->next;
p2 = p2->next->next;
}
ListNode* head1 = head;
ListNode* head2 = p1->next;
p1->next = NULL;
//reverse list2, to save space ,if stack ,O(n);then it is O(n) time,O(1) space
ListNode* p = head2;
ListNode* pre = NULL;
ListNode* next = NULL;
while(p!=NULL){
if(p->next==NULL) head2 = p;
next = p->next;
p->next = pre;
pre = p;
p = next;
}
//merge two lists
while(head2!=NULL){ //O(n)time
ListNode* next1 = head1->next;
ListNode* next2 = head2->next;
head1->next = head2;
head2->next = next1;
head2 = next2;
head1 = next1;
}
}
};