码迷,mamicode.com
首页 > 其他好文 > 详细

Leetcode:Reorder List 单链表重排序

时间:2014-04-29 13:42:21      阅读:427      评论:0      收藏:0      [点我收藏+]

标签:链表   leetcode   单链表   

Given a singly linked list LL0L1→…→Ln-1Ln,
reorder it to: L0LnL1Ln-1L2Ln-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}.

分析:观察重排前和重排后的序列,发现单链表前半部分各元素的相对顺序保持不变,而后半部分逆序。因此可将单链表一分为二,分成两个子链表;然后将后半部分子链表逆序;然后交叉合并这两个子链表得到结果链表。因此这个问题可分为三个子问题:

1)找出单链表的中间节点,以便将单链表一分为二;

2)将单链表后半部分逆置;

3)交叉合并两个子链表。

代码如下:

class Solution {
public:
    //返回单链表的中间节点
    ListNode *findMidNode(ListNode *head)
    {
        if(head == NULL)return NULL;
        ListNode *fast = head;
        ListNode *slow = head;
        while(fast->next && fast->next->next)
        {
            fast = fast->next->next;
            slow = slow->next;
        }
        return slow;
    }
    //单链表逆序
    ListNode *reverse(ListNode *head)
    {
        if(head == NULL)return NULL;
        ListNode *tail = NULL;
        ListNode *nxt = NULL;
        while(head != NULL)
        {
            nxt = head->next;
            head->next = tail;
            tail = head;
            head = nxt;
        }
        return tail;
    }
    //交叉合并两个单链表
    ListNode *crossMerge(ListNode *head1,ListNode *head2)
    {
        if(head1 == NULL)return NULL;
        if(head2 == NULL)return NULL;
        //设置辅助头结点,可在第一次插入节点时避免判断是否是头结点
        ListNode dummy(0);
        ListNode *tail = &dummy;
        ListNode *p = head1;
        ListNode *q = head2;
        while(p && q)
        {
            tail->next = p;
            tail = p;
            p = p->next;
            tail ->next = q;
            tail = q;
            q = q->next;
        }
        if(p)
        tail->next = p;
        if(q)
        tail->next = q;
        
        return dummy.next;
    }
    
    void reorderList(ListNode *head)
    {
        if(head == NULL || head->next == NULL)return;
        ListNode *mid_node = findMidNode(head);
        ListNode *head2 = mid_node->next;
        head2 = reverse(head2);
        mid_node->next = NULL;
        head = crossMerge(head,head2);
        return;
    }   
};

总结+牢骚:我觉得无论单链表的问题如何改变,差不多都可以将其划分为若干个基本子问题。这道题就是一个很典型的栗子。在找工作之前有必要把leetcode上关于单链表的题目多刷几遍!!!刷完题之后就写个leetcode单链表题目的总结吧!

Leetcode:Reorder List 单链表重排序

标签:链表   leetcode   单链表   

原文地址:http://blog.csdn.net/u012118523/article/details/24661037

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!