我的解法
没有什么需要推理的地方,要注意一开始要让cur走的比odd和even快,否则会导致cur的next被odd和even修改,代码里有注释。
ListNode *oddEvenList(ListNode *head) {
if (!head) {
return head;
}
ListNode *cur = nullptr, *headofOdd = head,
*headofEven = head->next ? head->next : nullptr;
if (!headofEven) {
return head;
}
ListNode *odd = headofOdd, *even = headofEven;
cur = head->next->next;
odd->next = even->next = nullptr;
if (!cur) {
odd->next = headofEven;
return headofOdd;
}
int cnt = 3;
while (cur) {
std::cout << cur->val << std::endl;
if (cnt & 1) {
odd->next = cur;
odd = cur;
} // 奇数
else {
even->next = cur;
even = cur;
}
cnt++;
cur = cur->next;
// 这两处记得把连接切断,否则会死循环
odd->next = nullptr;
even->next = nullptr;
}
odd->next = headofEven;
return headofOdd;
}
};
但是这个解法非常慢,25ms只超过了5.12%的人,肯定不是正解,故STFW。
正解
因为遍历链表的过程不可能再加速了,所以我们可以确定,问题就出在cnt上,我们加入的计数器导致了速度变慢。
解释都写在注释里。
ListNode *oddEvenList(ListNode *head) {
// 如果是空的或者只有一个点,就不用翻转了
if(!head || !head->next) {
return head;
}
auto cur = head, oddHead = cur, oddTail = cur;
auto evenHead = cur->next, evenTail = evenHead;
cur = cur->next->next;
while(cur) {
oddTail->next = cur;
oddTail = oddTail->next;
cur = cur->next;
if(cur) {
evenTail->next = cur;
evenTail = evenTail->next;
// 这里要记得再跳一下next,因为这个点已经处理过了
cur = cur->next;
}
// 这里之所以不用把odd和even的next都置为nullptr,是因为原来的写法一次只操作奇数或者
// 偶数当中的一个,奇数轮需要把偶数置空,反之同理,为了省去if判断,每次都全部置空
// 现在每次都会操作两个,就不需要了
}
evenTail->next = nullptr;
oddTail->next = evenHead;
return oddHead;
}
标签:Even,even,head,cur,nullptr,List,next,odd,Linked
From: https://www.cnblogs.com/smartljy/p/18489818