034-Reorder List

描述

给定一个单链表L:L0->L1->....->Ln-1->Ln,重新排列链表为这样的顺序:L0->Ln->L1->Ln-1....

使用原地操作,不可以修改节点的值;

分析

这道题目可以分为三部分:

1,找到单链表的中间节点,从此断开,将链表分为前、后两部分;

2,将后半部分单链表逆转;

3,将前后两个链表合并;

实现

//Reorder List
ListNode *reorderList(ListNode *head)
{
    ListNode *middle = findTheMiddleNode(head);
    ListNode *list2 = middle->next;
    ListNode *cur = head;
    
    middle->next = nullptr;
    
    // 逆转list2
    list2 = reverseWithHeadNode(list2);
    
    //依次插入list1 list2
    while (cur->next) {
        ListNode *next1 = cur->next;
        cur->next = list2;
        list2 = list2->next;
        cur->next->next = next1;
        cur = next1;
    }
    
    cur->next = list2;
    
    return head;
}

// Find the middle node
ListNode *findTheMiddleNode(ListNode *head)
{
    ListNode *slow = head;
    ListNode *fast = head;
    ListNode *middle = nullptr;
    
    while (fast && fast->next) {
        middle = slow;
        slow = slow->next;
        fast = fast->next->next;
    }
    
    return middle;
}

// reverse just with head node
ListNode *reverseWithHeadNode(ListNode *head)
{
    ListNode *prev = head;
    ListNode *cur = head->next;
    ListNode *next = cur->next;
    
    while (cur) {
        cur->next = prev;
        //移动指针
        prev = cur;
        cur = next;
        next = next?next->next:nullptr;
    }
    
    head->next = nullptr;
    
    return prev;
}

此算法的时间复杂度为O(n),空间复杂度为O(1)

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