143.Reorder List

来源:互联网 发布:淘宝店铺手机引流方法 编辑:程序博客网 时间:2024/04/28 09:53

题目描述:

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}.

---------------------------------------------------------------------------------------------------------------------------------------

本题如果是用普通数组进行存储的线性表结构的话,很好处理,一个指针从前往后,一个从后往前,错开进行插入就可以了。但是对于单链表而言,从前往后遍历是可以实现的,但是从后往前的遍历是不可能的,因此,就需要采用别的办法进行合并。

由于题目要求L0连接Ln,L1连接Ln-1,因此我们可以将链表的后半部分进行逆序,然后两个指针,一个指向头,一个指向逆序后头结点,然后进行错开插入,最终就可以得到结果了。

/** * Definition for singly-linked list. * struct ListNode { *     int val; *     ListNode *next; *     ListNode(int x) : val(x), next(NULL) {} * }; */  //初步想法是将链表的后半部分逆序,然后前半部分与逆序后的链表进行错开合并class Solution {public:    void reorderList(ListNode* head) {        if(head == NULL || head->next == NULL || head->next->next == NULL)            return;        //首先找到链表的中间节点        ListNode *mid = midNode(head);        ListNode *r = reverseList(mid->next);        mid->next = NULL;        head = merge(head, r);    }        ListNode* reverseList(ListNode *head)    {        if(head == NULL || head->next == NULL)            return head;        ListNode *pre = NULL;        ListNode *cur = head;        ListNode *cur_next = head->next;        while(cur->next != NULL)        {            cur->next = pre;            pre = cur;            cur = cur_next;            cur_next = cur_next->next;        }                //还有最后一个节点没有逆序        cur->next = pre;        return cur;    }        //找到链表的中间节点    ListNode *midNode(ListNode *head)    {        ListNode *slow = head;        ListNode *fast = head->next;        while(fast != NULL && fast->next != NULL)        {            fast = fast->next->next;            slow = slow->next;        }        return slow;    }        ListNode *merge(ListNode *l, ListNode *r)    {        //将两个链表错开插入,一般来说length(l) - length(r)要么为0,要么为1        ListNode *newhead = new ListNode(0);        ListNode *p = newhead;        //错开合并两个链表        while(r != NULL)        {            p->next = l;            l = l->next;            p = p->next;            p->next = r;            r = r->next;            p = p->next;        }        //最后要么l为空,要么还有一个元素,因此将p的下一个节点指向l        p->next = l;        return newhead->next;    }};

0 0
原创粉丝点击