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.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
方法1
递归解法
class Solution {
public:
void reorderList(ListNode *head) {
if(head==nullptr || (head->next)==nullptr || (head->next->next)==nullptr)
return;
ListNode *pre = head;
while((pre->next->next)!=nullptr)
pre=pre->next;
ListNode *temp = pre->next;
pre->next=nullptr;
ListNode *next = head->next;
head->next=temp;
temp->next=next;
//可以递归的原因是经过这个函数后不改变头节点
reorderList(next);
}
};
方法2
利用快慢指针
class Solution {
public:
void reorderList(ListNode *head) {
if(head==nullptr || (head->next)==nullptr || (head->next->next)==nullptr)
return;
ListNode *fast=head;
ListNode *slow=head;
while(fast->next && fast->next->next)
{
slow = slow->next;
fast = fast->next->next;
}
fast = slow->next;
slow->next = nullptr;
ListNode *second = reverseList(fast);
ListNode *p1 = head;
ListNode *p2 = second;
//后半部分的结点数量小于等于前半部分的结点数量(相差0或1)
while(p2!=nullptr)
{
ListNode *next1 = p1->next;
ListNode *next2 = p2->next;
p1->next = p2;
p2->next = next1;
p1 = next1;
p2 = next2;
}
}
ListNode *reverseList(ListNode *head)
{
if(head==nullptr || head->next==nullptr)
return head;
ListNode *last = nullptr;
ListNode *cur = head;
while(cur!=nullptr)
{
ListNode * temp = cur->next;
cur->next = last;
last = cur;
cur = temp;
}
return last;
}
};