Reorder List

题目链接
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; inext;
            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;
        }
    }

你可能感兴趣的:(Reorder List)