JZ35 复杂链表的复制

28 篇文章 0 订阅

描述

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。 下图是一个含有5个结点的复杂链表。图中实线箭头表示next指针,虚线箭头表示random指针。为简单起见,指向null的指针没有画出。

示例:

输入:{1,2,3,4,5,3,5,#,2,#}

输出:{1,2,3,4,5,3,5,#,2,#}

解析:我们将链表分为两段,前半部分{1,2,3,4,5}为ListNode,后半部分{3,5,#,2,#}是随机指针域表示。

以上示例前半部分可以表示链表为的ListNode:1->2->3->4->5

后半部分,3,5,#,2,#分别的表示为

1的位置指向3,2的位置指向5,3的位置指向null,4的位置指向2,5的位置指向null

如下图:

示例1

输入:

{1,2,3,4,5,3,5,#,2,#}

复制返回值:

{1,2,3,4,5,3,5,#,2,#}

标准做法:就地复制(则复制了所有指向信息),双指针遍历倍长链表,啥都有了

 千万注意,原链表一点不能变,一定要完整还原,否则判错

   public RandomListNode Clone2(RandomListNode pHead) {
        if(pHead==null) return null;
        RandomListNode p1=pHead,p2=pHead;
        //就近复制
        while (p1!=null){
            RandomListNode temp = new RandomListNode(p1.label);
            RandomListNode t=p1.next;
            p1.next=temp;
            temp.next=t;
            p1=t;
        }
        p1=p2.next;
        while (p1.next!=null){//p2原链找random  p1拷贝链表
            if(p2.random==null) p1.random=null;
            else p1.random=p2.random.next;
            p1=p1.next.next;
            p2=p2.next.next;
        }//暂时不能拆链表 一步步来
        p1=pHead.next;p2=pHead;
        RandomListNode ans=p1;
        while (p1.next!=null){
            p2.next=p2.next.next;
            p2=p2.next;//注意p2也要处理 原链表不能被破坏 否则判错

            p1.next=p1.next.next;//拷贝链p1在后,后处理 否则影响p2的拆下
            p1=p1.next;
        }
        p2.next=null;//原链表一点不能变
        return ans;
    }

脑子笨,做过的题都会,没做过的只会暴力

我得做法:最蠢暴力

public RandomListNode Clone(RandomListNode pHead) {
        RandomListNode ans=new RandomListNode(-1);
        RandomListNode ansHead = ans;
        RandomListNode p = pHead;
        //先克隆节点
        while (p!=null){
            RandomListNode temp = new RandomListNode(p.label);
            ans.next=temp;
            ans=ans.next;
            p=p.next;
        }

        //pHead.show();
        //再克隆随机指针
        ans=ansHead.next;
        p=pHead;
        while (p!=null){
            if(p.random==null) ans.random=null;//小心
            else ans.random=getNode(ansHead.next,getIndex(pHead,p.random));//千万注意每次从ansHead.next开头找
            p=p.next;
            ans=ans.next;
        }
        return ansHead.next;
    }

    public RandomListNode getNode(RandomListNode pHead,int k){
        while (--k!=0){
            if(pHead==null) return null;
            pHead=pHead.next;
        }
        return pHead;
    }

    public Integer getIndex(RandomListNode pHead,RandomListNode randomNode){
        if(randomNode==null) return null;
        int k=0;
        while (pHead!=null){
            k++;
            if(pHead==randomNode) break;
            pHead=pHead.next;
        }
        return k;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值