综合性很强的一个题目,运用到了中间结点查找和头插法逆序,在草稿纸上多写几个例子就能找到规律:转换后的链表最后一个结点始终是中间结点。于是从中间结点后分割,将后半部分逆序,然后间隔插入即可。
class Solution {
public:
ListNode *reverseList(ListNode *head)//逆序,头插法
{
if(!head||!head->next)
return head;
ListNode *p,*q;
p=head;//指向已插好的链表最后一个结点
q=p->next;//指向待插入结点
while(q)
{
p->next=q->next;
q->next=head;
head=q;
q=p->next;
}
return head;
}
void reorderList(ListNode *head) {
if(!head||!head->next)//如果链表为空或只有一个结点,直接返回
return ;
//否则,通过找到中间结点,将中间结点之后的链表(中间结点的下一个结点为头结点)逆序
ListNode *p,*q;//利用快指针和慢指针来得到中间结点的位置
p=head;
q=head;
ListNode *mid=NULL;
while(q&&q->next)
{
p=p->next;
q=q->next->next;
}
mid=p->next;
p->next=NULL;
mid=reverseList(mid);
p=head;
q=mid;
while(p&&q)
{
mid=mid->next;
q->next=p->next;
p->next=q;
p=q->next;
q=mid;
}
}
};