LeetCode143. Reorder List
原题地址
题目描述
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}.
思路
将原链表中点后的部分逆转插入到前面,并设置尾结点为NULL。
【我是用遍历链表然后设置尾结点为NULL的方法来去除链表中点后面的元素(逆转插入后原来中点后面的元素还在),总感觉有点麻烦,但也没想到更好的方法,如果谁有改进的方法,欢迎指出。】
代码实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
//输出链表
void print(ListNode* q){
while(q){
cout<<q->val;
q=q->next;
}
}
//逆转链表(创建一个新链表)
ListNode* reverse(ListNode* p){
ListNode* revL=NULL;
while(p){
ListNode* tmp=new ListNode(0);
tmp->val=p->val;
tmp->next=revL;
revL=tmp;
p=p->next;
}
return revL;
}
void reorderList(ListNode* head) {
if(head==NULL)//链表为空
cout<<NULL<<endl;
else if(head->next==NULL)//链表只有一个元素
cout<<head->val<<endl;
else if(head->next->next==NULL)//链表只有两个元素
cout<<head->val<<head->next->val<<endl;
else {
double length;//链表长度
ListNode* q=new ListNode(0);
q=head;
while(q){
length++;
q=q->next;
}
//找到链表的中间结点
double mid=ceil((length+1)/2);//链表中点
ListNode* p1=new ListNode(0);
p1=head;
ListNode* pmid=new ListNode(0);
pmid=head;
while(mid>1){
mid--;
pmid=pmid->next;
}
//逆转中间结点以后的结点
pmid=reverse(pmid->next);
//将逆转后链表中的结点插入原始链表中
ListNode* p2=pmid;
while(p2!=NULL){
//记录p1的下一个位置
ListNode* newp1=p1->next;
//插入结点
ListNode* tmp=new ListNode(0);
tmp->val=p2->val;
tmp->next=p1->next;
p1->next=tmp;
//p1,p2指向下一个位置
p1=newp1;
p2=p2->next;
}
//设置链表最后一个位置为NULL
ListNode* Lend=head;
while(length>1){
length--;
Lend=Lend->next;
}
Lend->next=NULL;
print(head);
}
}
};