其他分享
首页 > 其他分享> > 剑指offer:复杂链表的复制

剑指offer:复杂链表的复制

作者:互联网

剑指offer:复杂链表的复制

题目描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

输入描述

输入

img

返回

img

解题思路

一、暴力解法

  1. 复制正常的链表指针域
    这个操作比较简单,因为链表的下一个指针为形成一个串的,我们从头开始即可遍历所有的结点
  2. 复制随机的指针域
    这个操作有点麻烦,由于指针是随机指向的,因此无法通过一趟遍历来实现,这里我们采用暴力的方式,
    由于指针的位置是一一对应的,我们查找到原来的随机指针域在新链表中对应位置(O(N)O(N)),而我们遍历一遍将所有的随机指针都复制则需要O(N2),空间复杂度O(1)
    public RandomListNode Clone(RandomListNode pHead){
        if(pHead == null){  //原链表为空
            return null;
        }
        RandomListNode head = pHead;
        RandomListNode newhead = null , curhead = null;  //新链表头节点、当前节点
        while(head != null){
            RandomListNode node = new RandomListNode(head.label);
            head = head.next; //原链表移动
            if(curhead == null){    //新链表当前节点为空
                newhead = node;     //头节点赋值
            }else{
                curhead.next = node;//将新节点连接到新链表中
            }
            curhead = node; //当前节点移动
        }
        head = pHead; RandomListNode cur = newhead;
        while(head != null && cur != null){
            RandomListNode oldRand = head.random;  //旧节点的随机节点
            RandomListNode newRand = null;  
            newRand = findRand(pHead,newhead,oldRand); //找到新节点的随机节点在新链表的位置
            cur.random = newRand; //赋值随机节点
            cur = cur.next; //旧链表移动
            head = head.next; //新链表移动
        }
        return newhead; 
    }
    //查找随机节点在新链表的位置
    private RandomListNode findRand(RandomListNode oldhead,RandomListNode newhead,RandomListNode oldRand){
        RandomListNode old = oldhead;
        RandomListNode node = newhead;
        while(old != null && node != null){ //遍历新旧链表
            if(old == oldRand){  //找到随机节点在旧链表的位置
                return node;  
            }
            old = old.next;
            node = node.next;
        }
        return null;
    }

二、使用HashMap优化

  1. 复制正常的链表指针域

    这个操作比较简单,因为链表的下一个指针为形成一个串的,我们从头开始即可遍历所有的结点。

  2. 使用HashMap存储old.nodenew.node,因为新旧链表的node是一对一关系,所以使用get(old.node.random)可以获得new.node.random,然后赋值给newNode即可。

  3. 时间复杂度O(N),时间复杂度O(N)

    public RandomListNode Clone(RandomListNode pHead){
        if(pHead == null) return null;
        RandomListNode head = pHead;
        RandomListNode newHead = null, curNode = null;
        HashMap<RandomListNode,RandomListNode> map = new HashMap<>(); //创建新map
        while(head != null){
            RandomListNode node = new RandomListNode(head.label);
            map.put(head,node); //将新旧节点加入map
            if(curNode == null){
                newHead = node;
            }else{
                curNode.next = node;
            }
            head = head.next;
            curNode = node;
        }
        head = pHead; curNode = newHead;
        while(head != null && curNode != null){
            //根据旧节点的random获得新节点的random
            curNode.random = (RandomListNode)map.get(head.random); 
            curNode = curNode.next;
            head = head.next;
        }
        return newHead;
    }

三、复制拆分

preview

空间复杂度O(1),时间复杂度O(N)

    public RandomListNode Clone(RandomListNode pHead){
            if(pHead == null) return null;
            RandomListNode head = pHead;
            while(head != null){    //复制新节点并连接到旧链表
                RandomListNode node = new RandomListNode(head.label);
                node.next = head.next;
                head.next = node;
                head = node.next;
            }
            head = pHead;
            while(head != null){    //根据旧节点的random赋值新节点的random
                head.next.random = head.random == null ? null : head.random.next;
                head = head.next.next;
            }
            head = pHead;
            RandomListNode check = head.next;
            while(head != null){    //拆分
                RandomListNode node = head.next;    //新链表头节点
                head.next = node.next;  //将旧节点重新连接
                node.next = node.next == null ? null : node.next.next; //将新节点拆分出来
                head = head.next; 
            }
            return check;
        }

标签:node,head,RandomListNode,offer,next,链表,复制,null
来源: https://www.cnblogs.com/le-le/p/12458496.html