leetcode138. Copy List with Random Pointer

题目要求

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

假设存在这样一个链表,在链表的每个节点中,除了记录了自身值和指向下一个节点的指针,还有一个随机指针指向链表中任意一个节点。如今要求深度复制这份链表,在不改变原链表内容的状况下,建立一组新的对象,该组对象中的值和原链表中的值相同。node

思路一:map

由于任意节点指针的值在一遍遍历中是没法复制的。因此咱们能够基本肯定至少须要两次遍历才可以充分的复制链表。那么在第一次遍历的时候,咱们采用什么样的数据结构来记录第一次遍历的值呢?最直观的思路是使用map,第一次遍历时咱们访问next指针,将当前对象和当前对象的复制对象做为key-value值存入map中。第二次遍历时,咱们能够一边调整复制对象的next指针,一边调整复制对象的random指针,这两个指针指向的都将是map中源对象的复制对象。因此能够在两次遍历后完成任务。面试

public RandomListNode copyRandomList(RandomListNode head) {
        if(head==null) return null;
        Map<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();
        RandomListNode temp = head;
        while(temp!=null){
            map.put(temp, new RandomListNode(temp.label));
            temp = temp.next;
        }
        
        temp = head;
        while(temp!=null){
            RandomListNode cur = map.get(temp);
            cur.next = map.get(temp.next);
            cur.random = map.get(temp.random);
            temp = temp.next;
        }
        return map.get(head);
    }

思路二:利用链表的特性

那么咱们有没有可能在不使用map的状况下经过旧节点实现对新节点的检索?答案是确定的。咱们能够充分利用链表的特性来保存对新的复制节点的指针。第一圈遍历时,咱们能够将复制的节点插入至被复制的节点的后面。这样咱们就能够经过旧节点的next值找到新节点。在第二圈遍历的时候,咱们能够依次更新复制节点的random指针,将其指向新的复制节点。最后一圈遍历,咱们调整next指针,恢复原链表和塑造新链表。微信

public RandomListNode copyRandomList2(RandomListNode head) {
        if(head==null) return null;
        RandomListNode current = head, copyHead = null, copyCurrent = null;
        
        while(current!=null){
            RandomListNode temp = new RandomListNode(current.label);
            temp.next = current.next;
            current.next = temp;
            current = current.next.next;
        }
        
        current = head;
        while(current!=null){
            if(current.random!=null){
                current.next.random = current.random.next;
            }
            current = current.next.next;
        }
        
        current = head;
        copyCurrent = copyHead = head.next;
        head.next = head.next.next;
        while(current != null){
            current.next = current.next.next;
            copyCurrent.next = copyCurrent.next.next;
            copyCurrent = copyCurrent.next;
            current = current.next;
        }
        return copyHead;
    }

clipboard.png
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注个人微信公众号!将会不按期的发放福利哦~数据结构

相关文章
相关标签/搜索