Copy List with Random Pointer 解题报告

版权声明:转载请注明本文源地址 https://blog.csdn.net/qwe6112071/article/details/71599602

Copy List with Random Pointer

Description

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.

Challenge

Could you solve it with O(1) space?

实现思路一:基于哈希表

常规思路是我们可以维护一个哈希表,需要额外O(n)的空间复杂度。
每次复制的时候,将其随机节点作为键存到hash表中,值为新复制的节点。
如此循环一遍后,我们得到个依次连接的新的链表,同时一个对应的哈希表。
第二次同时对新旧链表进行遍历,每次以旧链表节点的随机节点(如果不存在,则不做任何操作)作为健,查找哈希表对应的的值(新链表节点),作为当前遍历到的新链表节点的随机节点。
根据此思路,求解方法如下:

/**
 * Definition for singly-linked list with a random pointer.
 * class RandomListNode {
 *     int label;
 *     RandomListNode next, random;
 *     RandomListNode(int x) { this.label = x; }
 * };
 */
public class Solution {
    /**
     * @param head: The head of linked list with a random pointer.
     * @return: A new head of a deep copy of the list.
     */
    public RandomListNode copyRandomList(RandomListNode head) {
        // write your code here
        if(head == null){
            return null;
        }
        HashMap<RandomListNode,RandomListNode> map = new HashMap<>();
        RandomListNode behead = head,newhead = new RandomListNode(-1),benewhead = newhead;
        while(head != null){
            RandomListNode newNode = new RandomListNode(head.label);
            newhead.next = newNode;
            newhead = newhead.next;
            map.put(head,newhead);
            head = head.next;
        }
        head = behead;
        newhead = benewhead.next;
        while(head != null){
            if(head.random != null){
                newhead.random = map.get(head.random);
            }
            head = head.next;
            newhead = newhead.next;
        }
        return benewhead.next;
    }
}

实现思路二:基于复制链表

思路一我们使用了额外的哈希表来存储映射关系,但利用相似的思路,结合链表的特性,我们可以去掉哈希表,将哈希表中oldnode->newnode的映射直接放到链表中。
假设原来节点为:
oldnode1->oldnode2->oldnode3->oldnde4
现在变成
oldnode1->newnode1->oldnode2->newnde2->oldnode4->newnode3->oldnode5->newnde4
当需要设置随机节点时,我们只需利用类似于哈希表的思路:newnode.random = map.get(head.random)
对于到这个新的“融合链表”中,就是:
oldnode.next.random = oldnode.random.next
这里注意做恒等比较,即:
1. oldnode.next(.random) = newnode(.random)
2. map.get(oldnode.random) = oldnode.random.next

/**
 * Definition for singly-linked list with a random pointer.
 * class RandomListNode {
 *     int label;
 *     RandomListNode next, random;
 *     RandomListNode(int x) { this.label = x; }
 * };
 */
public class Solution {
    /**
     * @param head: The head of linked list with a random pointer.
     * @return: A new head of a deep copy of the list.
     */
    public RandomListNode copyRandomList(RandomListNode head) {
        // write your code here
        if(head == null){
            return null;
        }
        RandomListNode behead = head;
        while(head != null){
            RandomListNode newNode = new RandomListNode(head.label);
            newNode.next = head.next;
            head.next = newNode;
            head = newNode.next;
        }
        head = behead;
        while(head != null){
            if(head.random != null){
                head.next.random = head.random.next;
            }
            head = head.next.next;
        }
        head = behead.next;
        while(head.next != null){
            head.next = head.next.next;
            head = head.next;
        }
        return behead.next;
    }
}

猜你喜欢

转载自blog.csdn.net/qwe6112071/article/details/71599602