[LeetCode]328. Odd Even Linked List

328. Odd Even Linked List

题意:

给一个链表, 要求把链表分为两部分, 一部分是奇数位置的数, 一部分是偶数位置的数. 奇数位置的数要在偶数位置的数前面, 并且数的相对位置不能改变.

解法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;
    }

你可能感兴趣的:([LeetCode]328. Odd Even Linked List)