剑指offer——复杂链表的复制(还不错,空间优先法和时间优先法)

面26
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)

思路:
如果只是完成顺序节点的复制(每个节点只有指向下一个节点的指针),那是简单的,边遍历边造节点即可。
重点是,每个节点还有一个random指针,指向任意节点。如果复制链表和旧链表之间是互相独立的状态,那个在复制链表中寻找节点的过程将是相当麻烦的。(只能一个个遍历)

所以一开始的复制,就要把新链表和旧链表融合起来。
a-a’-b-b’-c-c’-d-d’….
然后再做random赋值的处理
注意最后还要把新链表提取出来

不懂为何OJ过不了,本地跑出来是对的

    public RandomListNode Clone(RandomListNode pHead)
    {
        if(pHead==null)
            return null;
        RandomListNode head = new RandomListNode(pHead.label);
        head.next = pHead.next;
        pHead.next = head;
        RandomListNode node = head.next;
        while(node!=null){
            RandomListNode temp = new RandomListNode(node.label);
            temp.next = node.next;
            node.next = temp;
            node = temp.next;
        }
        while(pHead!=null){
            if(pHead.random!=null){
                pHead.next.random = pHead.random.next;
            }
            pHead = pHead.next.next;
        }
        node = head;
        while(node!=null){
            if(node.next!=null){
                node.next = node.next.next;
            }
            node = node.next;
        }
        return head;
    }

用map做

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

        node = head;  
        while (node != null) {  
            map.get(node).next = map.get(node.next);  
            map.get(node).random = map.get(node.random);  
            node = node.next;  
        }  

        return map.get(head);  
    }  

可以过OJ的

    public RandomListNode Clone(RandomListNode pHead){
        if(pHead==null)
            return null;
        RandomListNode pCur = pHead;
        //复制next 如原来是A->B->C 变成A->A'->B->B'->C->C'
        while(pCur!=null){
            RandomListNode node = new RandomListNode(pCur.label);
            node.next = pCur.next;
            pCur.next = node;
            pCur = node.next;
        }
        pCur = pHead;
        //复制random pCur是原来链表的结点 pCur.next是复制pCur的结点
        while(pCur!=null){
            if(pCur.random!=null)
                pCur.next.random = pCur.random.next;
            pCur = pCur.next.next;
        }
        RandomListNode head = pHead.next;
        RandomListNode cur = head;
        pCur = pHead;
        //拆分链表
        while(pCur!=null){
            pCur.next = pCur.next.next;
            if(cur.next!=null)
                cur.next = cur.next.next;
            cur = cur.next;
            pCur = pCur.next;
        }
        return head;        
    }

思路要清晰,尤其是这种迭代比较麻烦的,边画图边做

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值