复杂链表的复制

    坚持每天两道剑指offer,今天看到复杂链表的复制.之前是没接触过这类的题.看到提出的三种解法,也是开了自己的脑洞.

   第三种解法,只用O(n)的复杂度解决问题, 并且不需要额外的空间.

   记录一下三种解法,最后在实现最后一种

   复杂链表的结构

   

struct CompList{
    int data;
    CompList* next;
    CompList* others;
};
  next指针是正常指向下一个节点, others是指向其他的节点,也可以是空.

   L : a->b->c->d->e, a->others = c类似这样的.

   下面的三种方法都以上面的量表为例

  1.O(n^2)的复杂度

         先把上面的链表复制得到 a'->b'->c'->d'->e',接下来因为a->others = c 所以a'->others =c'

         这样,现在在L里找到c的位置需要走多少步,然后在L'内走相应的步数,在设置others指针,这样把整个链表遍历后既可以把L'的所有的others指针不为空的就可以设置好了.

        分析一下复杂度

        L' 里有n个节点, 每一个节点在设置others指针的时候都要从头遍历,走O(n)步,所以总的就是O(n^2)

       这种算法,一般都能想的出来,但是复杂度高,如果面试,面试官应该会提醒考虑复杂度低的算法


  2.以空间换时间O(n)空间,O(n)的时间

        首先也是先遍历L,   同时复制出L', 在复制的过程中我们用map做一个映射, map[a] = a'这样

        接下来去设置L'的others指针,  a'->others = map[a->others], 这样就可以设置L'的others指针了

  3.O(n)的时间完成

       首先是复制,复制的形式不同,

       (1)复制成a->a'->b->b'->c->c'->d->d'-e->e;

       (2)我们设置L'的others指针,a'->others = a->others->next;

       (3)把L'在链表里提出来变成

           a->b->c->d->e, a'->b'->c'->d'->e';

       实现第一步,复制链表

       

CompList* CloneNode(CompList* head){
    CompList* newNode = head;
    while(newNode != NULL){
        CompList* node = new CompList;
        node->data = newNode->data;
        node->others =NULL;
        node->next = newNode->next;
        newNode->next = node;
        newNode = node->next;
    }
    return head;
}

       实现第二步,设置L'的others指针

       

CompList* ConnectSiblingNodes(CompList* head){
    CompList&* Pnode = head;
    while(Pnode != NULL){
        CompList* node = Pnode->next;
        if(Pnode->others != NULL){
            node->others = Pnode->others->next;
        }
        Pnode = node->next;
    }
    return head;
}

      最后提取链表

       

CompList* ReconnectNodes(CompList* head){
    int flag = 0;
    CompList* node = head;
    CompList* CloneHead = NULL;
    CompList* CloneNode = NULL;
    if(node != NULL){
        CloneHead = CloneNode = node->next;
        node->next = CloneNode->next;
        node = node->next;
    }
    while(node != NULL){
        CloneNode->next = node->next;
        CloneNode = CloneNode->next;
        node->next = CloneNode->next;
        node = node->next;
    }
    return CloneHead;
}
     

继续坚持每天保证两道offer题,加油

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值