LeetCode 138 - 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.

Solution 1:

这种方法很直观,先遍历链表一次,拷贝next节点,并将原节点与拷贝过后的复制节点的映射关系用hashmap保存起来。然后再遍历一次链表,通过读取hashmap的映射关系来更新复制节点的random节点。

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

时间和空间复杂度均为O(n) 

 

Solution 2:

这个方法比较难想出来,不需要额外空间,不那么直观。直接上图比较好理解。分3步:

1,复制节点,并将拷贝后的节点放到原节点的后面。

2,更新所有拷贝节点的random节点:h.next.random = h.random.next。

3,将原链表与复制链表断开。



 

public RandomListNode copyRandomList(RandomListNode head) {
    if(head == null) return null;
    RandomListNode h = head;
    while(h != null) {
        RandomListNode copy = new RandomListNode(h.label);
        RandomListNode next = h.next;
        h.next = copy;
        copy.next = next;
        h = next;
    }
    h = head;
    while(h != null) {
        if(h.random != null)
            h.next.random = h.random.next;
        h = h.next.next;
    }
    
    h = head;
    RandomListNode newHead = h.next;
    while(h != null) {
        RandomListNode copy = h.next;
        h.next = copy.next;
        h = h.next;
        copy.next = h != null ? h.next : null;
    }
    
    return newHead;
}

 

Solution 3:

递归的方法更好理解:

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值