题目链接
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
You must do this in-place without altering the nodes' values.
For example,
Given {1,2,3,4}, reorder it to {1,4,2,3}.
解题历程:
一道链表题,刚开始看的时候没有任何思路,想着这要是数组那不是巨简单,但是它是一道链表题!想了想呢,只是想到一个指针从前往后先遍历一遍获取链表长度,然后设置一个cur指针从头遍历,另一个指针从后往前,但是从后往前的这个指针只能每次从前往后来获得,所以复杂度是n^2。
代码如下:
void reorderList(ListNode* head) {
int n = 0;
ListNode* cur = head;
ListNode* end = NULL;
ListNode* pre = NULL;
while (cur != NULL) {
cur = cur->next;
n++;
}
cur = head;
while (n > 1) {
end = cur;
pre = cur;
for (int i=0; i<n-1; i++)
end = end->next;
cur = cur->next;
pre->next = end;
if (cur == end)
end->next = NULL;
else
end->next = cur;
n = n - 2;
}
if (n == 1)
cur->next = NULL;
}
但是大神们肯定不满足于O(n^2)的复杂度…果然,首先先找出链表的中点,然后咔擦砍成两节,然后把后一节反转,之后再把第一节和第二节一个一个对应连接起来,复杂度O(n)。
void reorderList(ListNode* head) {
if (!head || !head->next)
return;
ListNode *p1 = head, *p2 = head->next;
while (p2 && p2->next) {
p1 = p1->next;
p2 = p2->next->next;
}
ListNode *pre = p1->next, *cur = p1->next->next, *next = NULL;
p1->next = NULL;
pre->next = NULL;
while (cur) {
next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
ListNode *cur1 = head;
ListNode *cur2 = pre;
while (cur1 && cur2) {
ListNode *tmp = cur1->next;
cur1->next = cur2;
cur2 = cur2->next;
cur1->next->next = tmp;
cur1 = tmp;
}
}