reorder-list

题目描述

Given a singly linked list LL 0→L 1→…→L n-1→L n,
reorder it to: L 0→L n →L 1→L n-1→L 2→L n-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}.

//测试版本
#include<iostream>
using namespace std;
struct ListNode {
    int val;
     ListNode *next;
     ListNode(int x) : val(x), next(NULL) {}
 };
class Solution {
public:
    void reorderList(ListNode *head) {
        if(head==nullptr||head->next==nullptr)
            return ;
        int sumNode=0;
        ListNode *q=head;
        while(q!=nullptr)
        {
            ++sumNode;
            q=q->next;
        }
        int cnt=(sumNode+1)/2-1;
        postptr(head,cnt,cnt);
        return ;
    }
private:
    void postptr(ListNode *&ptr,int n,int m)
    {
        if(n<=0) return ;
        ListNode *temp=ptr->next,*pre=ptr;
        while(temp->next!=nullptr)
        {
            pre=temp;
            temp=temp->next;
        }
        pre->next=nullptr;
        ListNode *p=ptr;
        for(int i=0;i<2*(m-n);++i)
            p=p->next;
        temp->next=p->next;
        p->next=temp;
        postptr(ptr,n-1,m);
        return ;
    }
};
ListNode* create(int n)
{
    ListNode *head=new ListNode(0);
    ListNode *p=head;
    for(int i=1;i<=n;++i)
    {
        ListNode *q=new ListNode(i);
        p->next=q;
        p=q;
    }
    p->next=nullptr;
    return head->next;
}
int main()
{
    int n;
    cin>>n;
    ListNode *head=create(n);
    cout<<"Original List is:";
    ListNode *p=head;
    while(p!=nullptr)
        {
            cout<<p->val<<" ";
            p=p->next;
        }
    Solution solve;
    solve.reorderList(head);
    p=head;
    cout<<"\nPostOrder List is:";
     while(p!=nullptr)
        {
            cout<<p->val<<" ";
            p=p->next;
        }
    cout<<"\nDone!"<<endl;
    return 0;
}

运行结果如下:

9
Original List is:1 2 3 4 5 6 7 8 9
PostOrder List is:1 9 2 8 3 7 4 6 5
Done!
Process returned 0 (0x0)   execution time : 3.689 s
Press any key to continue.
//循环版本AC
//思路:就是每次从链表尾部去除尾元素,插入原序列相应位置即可
class Solution {
public:
    void reorderList(ListNode *head) {
        if(head==nullptr||head->next==nullptr)
            return ;
        int sumNode=0;
        ListNode *q=head;
        while(q!=nullptr)
        {
            ++sumNode;
            q=q->next;
        }
        int cnt=(sumNode+1)/2-1;//插入次数
        for(int i=cnt;i>0;--i)
        postptr(head,i,cnt);
        return ;
    }
private:
    void postptr(ListNode *&ptr,int n,int m)
    {
        if(n<=0) return ; 
        ListNode *temp=ptr->next,*pre=ptr;
        while(temp->next!=nullptr)
        {
            pre=temp;
            temp=temp->next;
        }
        pre->next=nullptr;
        ListNode *p=ptr;
        for(int i=0;i<2*(m-n);++i)//寻找插入位置前驱元素
            p=p->next;
        temp->next=p->next;
        p->next=temp;
        return ;
    }
};
 
//递归版本,超时
class Solution {
public:
    void reorderList(ListNode *head) {
        if(head==nullptr||head->next==nullptr)
            return ;
        int sumNode=0;
        ListNode *q=head;
        while(q!=nullptr)
        {
            ++sumNode;
            q=q->next;
        }
        int cnt=(sumNode+1)/2-1;
        postptr(head,cnt,cnt);
        return ;
    }
private:
    void postptr(ListNode *&ptr,int n,int m)
    {
        if(n<=0) return ;
        ListNode *temp=ptr->next,*pre=ptr;
        while(temp->next!=nullptr)
        {
            pre=temp;
            temp=temp->next;
        }
        pre->next=nullptr;
        ListNode *p=ptr;
        for(int i=0;i<2*(m-n);++i)
            p=p->next;
        temp->next=p->next;
        p->next=temp;
        postptr(ptr,n-1,m);
        return ;
    }
};
//再次验证了最好不要用递归,易超时-_-

贴一下用快慢指针方法

public class Solution {
    public void reorderList(ListNode head) {
        if(head == null || head.next == null)
            return;
         
        // 快满指针找到中间节点
        ListNode fast = head;
        ListNode slow = head;
        while(fast.next != null && fast.next.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
        // 拆分链表,并反转中间节点之后的链表
        ListNode after = slow.next;
        slow.next = null;
        ListNode pre = null;
        while(after != null){
            ListNode temp = after.next;
            after.next = pre;
            pre = after;
            after = temp;
        }
        // 合并两个链表
        ListNode first = head;
        after = pre;
        while(first != null && after != null){
            ListNode ftemp = first.next;
            ListNode aftemp = after.next;
            first.next = after;
            first = ftemp;
            after.next = first;        
            after = aftemp;        
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值