143. 重排链表
给定一个单链表 L:L0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
给定链表 1->2->3->4, 重新排列为 1->4->2->3.
示例 2:
给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.
解题1:每次取尾部,插入前面
挨个next遍历取尾部,费时;
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
void reorderList(ListNode* head) {
if(!head) return;
int n=0;
ListNode * tmp=head;
while(tmp){
n++;
tmp=tmp->next;
}
//总共n个节点
ListNode* start=head;
ListNode* tail=head;
int t=0;
while(t<(n+1)/2){
for(int i=1;i<n;i++){
tail=tail->next; //第n个节点
}
Insert(start,tail);
start=start->next;
if(start) start=start->next;
t++;
tail=head;
}
if(start)
start->next=nullptr;
}
private:
void Insert(ListNode *a,ListNode *b){ //把b插入a后面
ListNode* t=a->next;
a->next=b;
b->next=t;
}
};
解法2:将链表变成数组,每次取尾部插入前面
取尾部的时间节省不少;
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
void reorderList(ListNode* head) {
if(!head) return;
ListNode *tmp=head;
while(tmp){
res.push_back(tmp);
tmp=tmp->next;
}
int start=0;
int tail=res.size()-1;
while(start<tail){
res[start++]->next=res[tail];
if(start<tail)
res[tail--]->next=res[start];
}
res[start]->next=nullptr;
}
private:
vector<ListNode*> res;
};
解法三:快慢指针分断
(1)快慢指针将链表分段
(2)逆序后半部链表
(3)组合到head即可;
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
void reorderList(ListNode* head) {
if(!head) return;
ListNode* one=head;
ListNode* two=head;
while(one&&two&&two->next){
one=one->next;
two=two->next->next;
}
ListNode* r=one->next;
one->next=nullptr;
r=reverse(r);
ListNode *tmp;
while(head&&r){
tmp=head->next;
head->next=r;
r=r->next;
head->next->next=tmp;
head=head->next->next;
}
}
private:
ListNode* reverse(ListNode* head){
if(!head) return nullptr;
ListNode dummyhead;
ListNode*p=&dummyhead;
p->next=head;
ListNode *tmp;
ListNode *f=head;
ListNode *r=f->next;
f->next=nullptr;
while(r){
if(r) {
tmp=r->next;
r->next=f;
p->next=r;
}
f=r;
r=tmp;
}
return dummyhead.next;
}
};