【LeedCode】单链表逆序从头到尾隔断插入

题目:

Given a singly linked list L: L 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}.

解析:

这里写图片描述

思路:

  • 方法一:利用链表的遍历
    • 1、从链表的头开始走,找到待插入结点的位置
    • 2、从链表的头开始走,找到需要插入的结点,从而将这个结点取出,同时将这个结点的前一个结点保存,再让其指向空,每次都从链表的头开始走
    • 3、直到链表的待插入位置全部找到,则停止遍历 (待插入结点与需要插入节点相邻)
      这里写图片描述
      缺陷:
      利用上面的方法,一般的时间复杂度较高O(n^2),不会符合面试官的需要,因此,我们需要找到一种更加简洁的方式,从而完成我们的需求。

    方法二:利用快慢指针

    • 1、利用快慢指针的思路,找到这条链表的中间结点,从而将这条链表分成两条链表
    • 2、对后半部分分出来的链表进行逆置
    • 3、对于形成的两条链表,在第一条链表上进行隔断插入
      这里写图片描述
    方案二核心代码:
void reorderList(ListNode *head) 
{
    if(head==NULL||head->next==NULL||head->next->next==NULL)
    return;
   //找这条链表的中间结点
    ListNode *slow=head;
    ListNode *fast=head;
    while((fast!=NULL)&&(fast->next!=NULL))
    {
      slow=slow->next;
      fast=fast->next->next;
    }
    //将后半部分的链表逆置
      ListNode *secondlist=slow->next;
   //将前后两部分分为了两条链表
      slow->next=NULL;
    //逆置
      ListNode *pre=NULL;
      slow=secondlist;
      fast=secondlist->next;
      while(slow!=NULL)
      {
    //退出之后,则pre为头结点
      slow->next=pre;
      pre=slow;
      slow=fast;
      if(fast)
      {
        fast=fast->next;
      }
    //将第二条链表插入到第一条中
      slow=head;
      fast=head;
      while(slow&&pre)
      {
      if(fast)
      fast=slow->next;
      slow->next=pre;
      pre=pre->next;
      slow->next->next=fast;
      slow=fast;
      }
    }

结语

俗话说leedCode为面试经典,今天尝试做了一道题,果然名不虚差呢,嘿嘿,加油,致优秀的自己!!!

猜你喜欢

转载自blog.csdn.net/qq_41035588/article/details/81784981