第23题 Copy List with Random Pointer

本文介绍两种深拷贝含额外随机指针的链表方法:使用HashMap存储对应关系及在原节点后直接插入新节点的方式。第一种方法时间复杂度O(n),空间复杂度O(n);第二种方法虽改变原链表结构但不使用额外空间。

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.

Solution1:HashMap的方法

/**
 * 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 {
    public RandomListNode copyRandomList(RandomListNode head) {
        if(head==null) return null;
        Map<RandomListNode, RandomListNode> amap = new HashMap<RandomListNode, RandomListNode>();
        RandomListNode newHead = new RandomListNode(head.label);
        RandomListNode cur=newHead, oldCur=head;
        amap.put(oldCur,cur);
        while(oldCur.next!=null){
            oldCur=oldCur.next;
            RandomListNode next=new RandomListNode(oldCur.label);
            cur.next=next;
            cur=cur.next;
            amap.put(oldCur,cur);
        }
        cur.next=null;
        cur=newHead; 
        oldCur=head;
        while(cur!=null){
            RandomListNode random = oldCur.random;
            if(random==null) cur.random=null;
            else{
                random = amap.get(random);
                cur.random = random;
            }
            cur=cur.next;
            oldCur=oldCur.next;
        }
        return newHead;
    }
}
第一遍遍历list并创建hashmap中相应key-value pair用了O(n),第二遍查找hashmap得到random的值,用了O(n),最后时间复杂度为O(n), 空间复杂度O(n)。

Solution2:Node-attached-as-next-node方法。没新建一个new list中的节点,就将其插入原节点与原节点的next之间。这样每个新节点的random值可以通过原节点的random的next获得。这种方法优点在于不用建立hashmap,只需建立新的list,节省了空间。缺点是在做deep copy的过程中需要改变原list,不是很安全。

/**
 * 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 {
    public RandomListNode copyRandomList(RandomListNode head) {
        if(head==null) return null;
        RandomListNode oldPtr =head, newPtr=null;
        //build new list, change the structure of the old list
        while(oldPtr!=null){
            newPtr = new RandomListNode(oldPtr.label);
            newPtr.next = oldPtr.next;
            oldPtr.next=newPtr;
            oldPtr = oldPtr.next.next;
        }
        oldPtr=head;
        RandomListNode newHead = oldPtr.next;
        //set the random pointer for new list
        while(oldPtr!=null){
            if(oldPtr.random!=null)
                oldPtr.next.random = oldPtr.random.next;
            oldPtr=oldPtr.next.next;
        }
        //recover the old list, correct the new list
        oldPtr=head;
        newPtr=newHead;
        while(oldPtr!=null){
            newPtr=oldPtr.next;
            oldPtr.next=oldPtr.next.next;
            if(newPtr.next!=null) newPtr.next=newPtr.next.next;
            oldPtr=oldPtr.next;
        }
        return newHead;
    }
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值