问题描述
将给定的单链表L: L 0→L 1→…→L n-1→L n,
重新排序为: L 0→L n →L 1→L n-1→L 2→L n-2→…
要求使用原地算法,并且不改变节点的值
例如:
对于给定的单链表{1,2,3,4},将其重新排序为{1,4,2,3}.
解决方案
- 首先用快慢指针找到链表的中间
- 将第一个链表和第二个链表断开,并将第二个链表逆序
- 将两个链表依次合并
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
typedef ListNode node;
void reorderList(ListNode *head) {
if(head==NULL ||head->next==NULL)return;
//找到链表中点
node *middle=getMiddle(head);
node *after=middle->next;//断链
middle->next=NULL;
node *pre=NULL;
//第二个链表逆序
while(after!=NULL){
node *temp=after;
after = temp->next;
temp->next=pre;
pre=temp;
}
//合并两个链表
node *l1=head;
node *l2=pre;
while(l1!=NULL&&l2!=NULL){
node *temp1=l1->next;
node *temp2=l2->next;
l1->next=l2;
l2->next=temp1;
l1=temp1;
l2=temp2;
}
}
node *getMiddle(node *head){
node *chaser=head;
node *runner=head;
while(runner->next!=NULL&&runner->next->next!=NULL){
chaser=chaser->next;
runner=runner->next->next;
}
return chaser;
}
};
note:
1、快慢指针是对runner判断,否则会出错
2、第一个链表要和第二个链表断开,即middle->next=NULL