Copy List with Random Pointer


 拥有next指针和random指针随机指向链表中任意的一个结点,对此进行深复制

我的做法,先顺序的方式把next指针指向复制,然后让原来的和复制的节点一一对应,

使用HashMap进行K-V映射,然后遍历一次,使得random指针的进行深复制

/**
 * 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) {
        RandomListNode copyHead = null, Nnext = head, pre = null, next = null;
        HashMap<RandomListNode, RandomListNode> map = new HashMap<>();
        while(Nnext != null){
            next = new RandomListNode(Nnext.label);
            if(copyHead == null){
                pre = copyHead = next;
            }else{
                pre.next = next;
                pre = pre.next;
            }
            map.put(Nnext, pre);
            Nnext = Nnext.next;
        }
        Nnext = head;
        while(Nnext != null){
            pre = map.get(Nnext);
            next = map.get(Nnext.random);
            pre.random = next;
            Nnext = Nnext.next;
        }
        return copyHead;
    }
}


在leetcodeOJ上的Discuss有一个O(N)时间复杂度的,O(1)空间复杂度的C++,

经过一次模拟之后,里面的的技巧非常好,原来的链表假设是


将深复制的节点一次跟在原来相应节点的后面


那么现在容易知道,深复制的node的random指向的是会是相应原来节点random节点的next节点了,

一次遍历就可以将原始node,和深复制的node分离和合并


RandomListNode *copyRandomList(RandomListNode *head) {
    if(head == NULL) return NULL;
    RandomListNode *p = head;
    do {
        RandomListNode *q = p->next;
        p->next = new RandomListNode(p->label);
        p->next->next = q;
        p = q;
    } while(p != NULL);
    p = head;
    do {
        p->next->random = (p->random == NULL) ? NULL : p->random->next;
        p = p->next->next;
    } while(p != NULL);
    p = head;
    RandomListNode *r = head->next;
    for(RandomListNode *q = r;;) {
        p->next = q->next;
        p = p->next;
        if(p == NULL) break;
        q->next = p->next;
        q = q->next;
    }
    return r;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值