题目链接:leetcode143
题面
题目大意
略
解题思路
首先用快慢指针找到链表的中点,并分成两个链表,为了方便操作,前面的链表的长度要大于等于后面的链表;
接着,把后面的链表逆置,为了方便操作,前面链表的链尾可以暂时称位后面链表的头节点;
最后将两个链表归并,由于归并操作要交替插入,于是我们结束的标志是后面链表完全插入到前面的链表的时候算法结束,这也是为什么我们要使得前面的链表元素不小于后面链表的原因。
时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( 1 ) O(1) O(1)。
代码实现
/**
* 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 == NULL) return ;
ListNode *q, *p, *newHead;
//找到中点 分为两条链表
q = p = head;
while (q && q->next) {
p = p->next;
q = q->next->next;
}
newHead = p; //前面的链表的尾指针充当后面链表的头节点
//逆置后面的链表
q = newHead->next;
newHead->next= NULL;
while (q) {
p = q->next;
q->next = newHead->next;
newHead->next = q;
q = p;
}
//合并两个链表
q = newHead;
newHead = newHead->next;
q->next = NULL;
q = head->next; p = newHead; newHead = head;
while (p) {
newHead->next = p;
newHead = p;
p = q;
q = newHead->next;
}
return ;
}
};