题意:
给一个链表, 要求把链表分为两部分, 一部分是奇数位置的数, 一部分是偶数位置的数. 奇数位置的数要在偶数位置的数前面, 并且数的相对位置不能改变.
解法1:
将整个链表拆分为奇数表和偶数表, 在从头到尾遍历整个链表的过程中, 用一个count变量进行计数.
计数位置为奇数的加到奇数表里, 计数位置为偶数的加到偶数表里. 最后再把奇数表和偶数表连在一起.
时间复杂度O(n), 空间复杂度O(1)
ListNode* oddEvenList(ListNode* head) {
if (head == NULL)
return head;
ListNode* even_head;
if (head->next != NULL)
even_head = head -> next;
else
return head;
int count = 1;
ListNode *p = head->next->next;
ListNode *oddp = head;
ListNode *evenp = even_head;
while (p != NULL) {
if (count % 2 != 0) {
oddp->next = p;
oddp = oddp->next;
}
else {
evenp->next = p;
evenp = evenp->next;
}
count++;
p = p->next;
}
evenp->next = NULL;
oddp->next = even_head;
return head;
}
解法2(推荐)
解法1需要计数器, 不够优雅.
考虑到奇数位置后面肯定会是一个偶数位置, 所以在遍历链表的过程中, 可以轮流将Node插入到奇链表和偶链表中.
在这种方法中, 需要注意空指针的排查, 详情见注释.
时间复杂度O(n), 空间复杂度O(1)
ListNode* oddEvenList(ListNode* head) {
if (!head)
return head;
ListNode *evenhead = head->next;
ListNode *even = evenhead;
ListNode *odd = head;
while (odd->next && even->next){ //必须先判断奇数, 再判断偶数, 因为有可能整个链表就一个数.
odd->next = even->next; //[先] 必须先加入奇数位置, 再加入偶数位置. 因为初始化时, 偶数位置是靠奇数位置确定的.
odd = odd->next;
even->next = odd->next; //[后]
even = even->next;
}
odd->next = evenhead;
return head;
}