LeetCode | Reorder List

100 篇文章 0 订阅
13 篇文章 0 订阅

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

又是一个链表改序的问题,古老的办法当然是每次找最末尾,然后将最末尾插入到前面想要的位置。
然后发现一个很大很大的用例TLE了

        //可以看到,暴力的办法超时了
        for(ListNode* cur=head;i<n/2;i++){
            //获取到最后一个节点
            temp=cur;
            ListNode* t=temp->next;
            int count=1;
            //不能少于3个元素才能进行交换
            for(;t->next!=NULL;t=t->next,temp=temp->next) count++;

            //得到t为最后一个节点
            if(count<2) break;

            t->next=cur->next;
            cur->next=t;
            cur=cur->next->next;

            //找到temp前一个设置为队尾
            temp->next=NULL;

            //break
            if(cur==NULL) break;
        }

正确的办法应当是算出后面有多少元素需要倒置,然后倒置它们,将这些链表提取出来依次插入另一个链表
处理一些莫名的re之后就可ac

class Solution {
public:
    void reorderList(ListNode* head) {
        if(head==NULL) return;
        ListNode root(-1),new_head(-1);
        root.next=head;

        int n=1,i=0;//计算链表的长度
        ListNode* temp=head;
        for(;temp->next!=NULL;n++,temp=temp->next);
        if(n<=2) return;//2个节点以内不需要进行处理
        int k=(n-1)/2;

        //可以确定这个end是目的链表的end
        ListNode *end=head;
        for(int i=0;i<n/2;i++,end=end->next);
        //划分为两个链表
        new_head.next=end->next;
        end->next=NULL;

        //反转第二链表
        reverse(&new_head,new_head.next,temp);

        //将第二链表插入第一链表
        for(ListNode *st=head,*sub=new_head.next,*stmp=NULL;sub;){
            stmp=sub->next;
            sub->next=st->next;
            st->next=sub;
            st=sub->next;
            sub=stmp;
        }

    }


    ListNode* reverse(ListNode* preNode,ListNode* begin,ListNode* end){
        //首尾是一个节点。不需要处理 
        if(begin==end) return begin;
        ListNode* end_next=end->next;
        for(ListNode *p=begin,*cur=p->next,*next=cur->next;
            cur != end_next;
            p=cur,cur=next,next=next?next->next:NULL){
                cur->next=p;
        }
        begin->next=end_next;
        preNode->next=end;
        return begin;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值