原题:
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 看这个形式,明显是把链表的后半段插入前半段的各个元素的中间间隔,而且是倒着插入,于是就可以利用栈,把整个链表入栈后,则后半段是栈顶的前n/2个元素(这里有奇数和偶数的区别)。如图:
2 具体插入的时候需要好好看看,如图
3 在插入的时候需要判断奇数和偶数,偶数的时候有一个情况就是会造成死循环。。。。如图:
4 在以上还有一个问题,就是这个链表没有null结尾,所以最后也会有问题,
解决方法1:
如代码1,每次把end的next都先指向NULL,然后再进行操作
代码1(328ms):
class Solution {
public:
void reorderList(ListNode *head) {
stack<ListNode*> s;
ListNode * l = head;
while(l){
s.push(l);
l = l->next;
}
int insertSize = s.size()/2;
l=head;
for(int i = 0;i<insertSize;i++){
ListNode * end = s.top();
s.pop();
s.top()->next = NULL;
//end->next = l->next;
//l->next = end;
//l=l->next->next;
if(l->next!=end){
end->next = l->next;
l->next = end;
l=l->next->next;
}
}
}
};
解决方法2:
如代码2,判断是否是奇数个元素,如果是就current->next=NULL,如果是偶数,就把end指向null,如图
代码2(316ms):
class Solution {
public:
void reorderList(ListNode *head) {
stack<ListNode*> s;
ListNode * current = head;
while(current){
s.push(current);
current = current->next;
}
int insertSize = s.size()/2;
bool cmp = (s.size()%2==0)?true:false;
current=head;
ListNode * end ;
for(int i = 0;i<insertSize;i++){
end = s.top();
s.pop();
if(current->next!=end){
end->next = current->next;
current->next = end;
current=current->next->next;
}
}
if(cmp){
end->next=NULL;
}
else{
current->next=NULL;
}
}
};