问题描述:
- 给定一个单链表
L
的头节点 head
,单链表 L
表示为:
L0 → L1 → ... → Ln-1 → Ln
- 将其重新排列后变为:
L0 → Ln → L1 → Ln-1 → L2 → Ln-2 → ...
- 不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
核心思路:
- 该题并不难,只是较为繁琐。
- 分为三个步骤:快慢指针移动找到中点、断开前后段后反转后半段、将前半段和反转后的后半段合并。
- 实际上也可以直接用递归来处理,但递归只是代码上稍微短一些,开销其实更大,在该题下写递归确实是没有必要。
代码实现:
class Solution
{
public:
void reorderList(ListNode* head)
{
if(!head or !head->next) return;
ListNode* slow = head;
ListNode* fast = head->next;
while(fast and fast->next)
slow = slow->next, fast = fast->next->next;
ListNode* cur = slow->next;
ListNode* pre = nullptr;
ListNode* next;
slow->next = nullptr;
while(cur)
{
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
cur = head;
while(cur and pre)
{
ListNode* tmp1 = cur->next;
ListNode* tmp2 = pre->next;
cur->next = pre;
pre->next = tmp1;
cur = tmp1;
pre = tmp2;
}
return;
}
};