这道题我开始想着用两个循环,最后一个节点插在当前节点的后面,用了两个循环,这样时间复杂度会达到O(N^2),超时了。
错误示范
class Solution {
public:
void reorderList(ListNode* head)
{
ListNode *p=head;
while(p)
{
ListNode *q=p;
while(q->next&&q->next->next)
q=q->next;
if(q->next==NULL)
break;
ListNode *last=q->next;
q->next=last->next;
last->next=p->next;
p->next=last;
p=last->next;
}
return ;
}
};
第二种方法:先确定链表的中点,将链表分成前后两部分,后面的链表逆置,然后依次插入前面的链表中。
class Solution {
public:
void reorderList(ListNode* head)
{
ListNode *slow=head;
if(!slow)
return;
ListNode *fast=slow->next;
if(!fast)
return;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
ListNode* back=slow->next;
slow->next=NULL;
ListNode *p=head;
ListNode *q=reverse(back);
while(q)
{
ListNode *s=new ListNode(q->val);
s->next=p->next;
p->next=s;
p=s->next;
q=q->next;
}
}
ListNode * reverse(ListNode *L)
{
ListNode *dummy=NULL;
while(L)
{
ListNode *t=L->next;
ListNode *p=L;
p->next=dummy;
dummy=p;
L=t;
}
return dummy;
}
};
但是我在逆置的时候用了额外的空间,其实可以就地逆置,用三个指针就好了。
class Solution {
public:
void reorderList(ListNode* head)
{
ListNode *slow=head;
if(!slow)
return;
ListNode *fast=slow->next;
if(!fast)
return;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
}
ListNode* back=slow->next;
slow->next=NULL;
ListNode *p1=back->next;
back->next=NULL;
while(p1)//进行逆转
{
ListNode* p2=p1->next;
p1->next=back;
back=p1;
p1=p2;
}
ListNode *p=head;
ListNode *q=back;
while(q)
{
ListNode *s=new ListNode(q->val);
s->next=p->next;
p->next=s;
p=s->next;
q=q->next;
}
}
};