此题思路比较简单,分为三步:
1.利用快慢指针,将链表从中间断开。
2.翻转右半部分链表
3.将两个链表合并
首先,是我提交的第一个版本,耗时880mm,非常的慢
ListNode *reverseList(ListNode *head){
if(NULL==head)return NULL;
if(NULL==head->next)return head;
ListNode *t=head->next;
head->next=NULL;
ListNode *ret=reverseList(t);
t=ret;
while(NULL!=t->next)t=t->next;
t->next=head;
return ret;
}
ListNode *mergeList(ListNode *left, ListNode *right){
ListNode *p=left,*q=right;
while(q){
ListNode *lt=p->next,*rt=q->next;
p->next=q;q->next=lt;q=rt;p=lt;
}
return left;
}
void reorderList(ListNode *head) {
if(NULL==head)return;
ListNode *p=head,*q=head->next,*right;
while(q){
q=q->next;
if(NULL!=q)q=q->next;
else{
continue;
}
p=p->next;
}
right=p->next;
p->next=NULL;
right=reverseList(right);
head=mergeList(head,right);
}
问题主要有:
1.翻转链表的时候,我使用的是递归的写法,递归效率还是非常低,能不用就不用吧。
2.快慢指针的使用并不熟练,此方法可以统计链表顶点数量
3.在断开链表时,一点要有断开的语句(这个非常重要,否则可能出现循环节点,并且不利于调试)
我参考了此大牛Acm之家的写法对程序稍微做了改进,下面是我提交的第二版本,耗时104mm,效率还不是很高,不过已经很好了,
如果有效率更高的方法,请各位技术朋友留言告诉我啊。
ListNode *mergeList(ListNode *left, ListNode *right){
ListNode *p=left,*q=right;
while(q){
ListNode *lt=p->next,*rt=q->next;
p->next=q;q->next=lt;q=rt;p=lt;
}
return left;
}
void reorderList(ListNode *head) {
if(NULL==head || NULL==head->next)return;
ListNode *slow,*quick,*right;
slow=quick=head;
while(NULL!=quick->next && NULL!=quick->next->next){
slow=slow->next;
quick=quick->next->next;
}
right=slow->next;
slow->next=NULL;
ListNode *q=right->next;
right->next=NULL;
while(q){
ListNode *pre=q;q=q->next;
pre->next=right;right=pre;
}
head=mergeList(head,right);
}