这道题是道综合题,把三个知识点串起来,非常适合复习链表处理的三个技巧
【思路】:观察发现可以把链表后一半进行反转,然后当成两个链表的合并任务即可
class Solution {
public:
void reorderList(ListNode* head) {
if (!head) return;
// 1.寻找链表中点(快慢指针)
auto premid = findmid(head);
// 2.链表反转(pre/cur/next)
reverse(premid);
auto l1 = head;
auto l2 = premid->next;
premid->next = nullptr;
// 3.链表合并(先保存next然后穿针引线)
merge(l1, l2);
}
// 合并链表
void merge(ListNode* l1, ListNode* l2) {
while (l1 && l2) {
// 先保存两个链表的next
auto l1next = l1->next;
auto l2next = l2->next;
// 穿针引线
l1->next = l2;
l2->next = l1next;
// 两指针同时前移
l1 = l1next;
l2 = l2next;
}
}
// 反转链表
void reverse(ListNode* prehead) {
auto pre = prehead;
auto cur = prehead->next;
while (cur && cur->next) {
auto next = cur->next;
cur->next = next->next;
next->next = pre->next;
pre->next = next;
}
}
// 找链表中点
ListNode* findmid(ListNode* head) {
auto fast = head, slow = head;
while (fast && fast->next) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
};