zoukankan      html  css  js  c++  java
  • [LeetCode] Reorder List 反向插入链表

    Given a singly linked list LL0→L1→…→Ln-1→Ln,
    reorder it to: L0→LnL1→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}.

    Hide Tags
     Linked List
     

     
      这题如果使用额外空间,挺容易实现的,确定了中间位置,然后后边的放入stack,然后从新构建链表。空间为O(n)。
      如果不用额外空间,便使用栈空间,通过递归实现,这样逻辑比较复杂。
    思路:
    1. 确定链表分开的点。
    2. 进入递归函数,递归到后半段的末尾。
    3. 递归函数返回前构建链表。

      这个很多细节,例如确定分开的点,如果node=4,

    1 2 3 4   ->     1 4 2 3.

         这样断开的位置其实是左起第三个,而node=5时,同样断开位置也是左起第三个,一步到位的方法是使用快慢索引,先快移1步,然后慢移一步,最后快移一步,这样不需要额外的变量。

            while(1){
                if(fast->next!=NULL)    fast=fast->next;
                else    break;
                slow=slow->next;
                if(fast->next!=NULL)    fast=fast->next;
                else    break;
            }

      然后是递归函数,因为是单项链表,传递的变量有

    void help_f(ListNode * &lft,ListNode * rgt)

      前一个有引用,后一个没有,因为单项索引的约束,前半段需要不断后移,可以是同一个,这样省点空间,而后半段需要每次使用变量标记,所以不能够使用引用。

    最终代码如下,时间非常的好26ms,排名统计中太前没有显示了:

    #include <iostream>
    #include <queue>
    using namespace std;
    
    /**
     * 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)  return;
            ListNode *fast=head,*slow=head;
            while(1){
                if(fast->next!=NULL)    fast=fast->next;
                else    break;
                slow=slow->next;
                if(fast->next!=NULL)    fast=fast->next;
                else    break;
            }
            ListNode * fnl_end=slow;
            fast=fnl_end;
            slow=head;
            help_f(slow,fast);
            fnl_end->next=NULL;
            return ;
        }
        void help_f(ListNode * &lft,ListNode * rgt)
        {
            if(rgt!=NULL)   help_f(lft,rgt->next);
            else return ;
            rgt->next=lft->next;
            lft->next=rgt;
            lft=rgt->next;
        }
    };
    
    int main()
    {
        ListNode n1(1),n2(2),n3(3),n4(4),n5(5);
        n1.next=&n2;
        n2.next=&n3;
        n3.next=&n4;
    //    n4.next=&n5;
        Solution sol;
        sol.reorderList(&n1);
        ListNode *tmp = &n1;
        while(tmp!=NULL){
            cout<<tmp->val<<endl;
            tmp=tmp->next;
        }
        return 0;
    }
  • 相关阅读:
    Hibernate session.save()实体类,主键增长问题
    安装原版 Windows 7 后需要安装的微软更新 和 必备系统组件
    如何使用站群程序来批量建网站?
    Android图片优化指南
    SQLite为何要用C语言来开发?
    Kotlin使用率达35%,Java要退位了?
    JavaScript的几种循环使用方式及性能解析
    30 分钟理解 CORB 是什么
    PHP 字符串相关常识
    那些10w+的公众号都在写什么?
  • 原文地址:https://www.cnblogs.com/Azhu/p/4209848.html
Copyright © 2011-2022 走看看