Reorder List leetcod

2015-01-24 05:44:51 · 作者: · 浏览: 3

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→L1→…→Ln-1→Ln, 重新排序之后变成 L0→Ln→L1→Ln-1→L2→Ln-2→…

思路: 可以看成是两个链表进行合并,现拆分 L0→Ln→L1→Ln-1→L2→Ln-2→… 变成:

L0 L1 L2 .......

Ln Ln-1 Ln-2 .....

所以我们可以将 L0→L1→…→Ln-1→Ln, 折半拆分,变成 L0 L1 L2 .....Ln/2 和 Ln/2 Ln/2+1 ....Ln

然后将后半部分进行逆置 ,变成L0 L1 L2 .......,Ln Ln-1 Ln-2 ..... 再将两链表合并

拆分过程在链表归并排序中曾遇到过 Sort List ,定义一快一慢指针,快的一次走两步,慢的一次走一步,遍历链表,最后慢的 的下一个节点为后半部分。

代码如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode * reorderList(ListNode *head) {
        
        if(head==NULL||head->next==NULL||head->next->next==NULL)
                return head;        
        ListNode *fast,*showl;//定义fast和showl用来找到链表的中点
        fast=head;
        showl=head;
        
        while(fast->next!=NULL&&fast->next->next!=NULL)
        {
            fast=fast->next->next;//fast一次走两步
            showl=showl->next;//showl 一次走一步
        }
        
       // ListNode *halfafter=new ListNode()
        ListNode *start,*pur,*q;
        
        start=showl->next;//start表示 下一半节点的开始
      
        
        //将以start开始的后半节点逆置
        pur=start;
        
        while(start!=NULL)
        {
            q=start;
            start=start->next;
            q->next=showl->next;
            showl->next=q;
        }
        pur->next=NULL;
        
        ListNode *p,*qur;
        p=head;            //前半部分第一个节点
        q=showl->next; //后半部分第一个节点
        showl->next=NULL;//断开链表
        while(q!=NULL)
        {
            pur=p->next; //用来保存前半部分的下一个节点
            qur=q->next; //用来保存后半部分的下一个节点
            
            p->next=q;
            q->next=pur;
            
            p=pur;
            q=qur;
        }
        
        return head;
        
    }
};