题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
解题思路
参考https://www.nowcoder.com/profile/1687题解
完全不懂深复制的含义--将所有的节点以及节点之间的指针复制一遍
重复下两种方法的思路
方法一:
1.复制下所有的节点,并将映射关系用hashmap存储
2.遍历原链表,将指针关系添加到映射的新节点上
3.返回新链表--代码如注释部分
方法二:
1.先遍历,复制所有节点,插入到原节点右侧
2.再遍历,将所有的指针关系添加到新节点上
2.最后遍历实现新旧链表的分离(分离之后原来的链表也得是一个链表)
具体见下图
图片说明
java代码

/*
public class RandomListNode {
    int label;
    RandomListNode next = null;
    RandomListNode random = null;

    RandomListNode(int label) {
        this.label = label;
    }
}
*/
import java.util.*;
public class Solution {
//     public RandomListNode Clone(RandomListNode pHead)
//     {
//         //使用hashMap来存放随意指针的对应关系
//         HashMap<RandomListNode,RandomListNode> map=new HashMap<>();
//         RandomListNode p=pHead;
//         //先将所有节点复制一遍,并保存映射关系
//         while( p != null){
//             RandomListNode node=new RandomListNode(p.label);
//             map.put(p,node);
//             p=p.next;
//         }
//         //再遍历一遍,处理好指针问题
//         p=pHead;
//         while( p != null){
//             RandomListNode node=map.get(p);//得到新节点
// //             if(p.next==null)  node.next=null;
// //             else node.next=map.get(p.next);
//             node.next=(p.next == null)? null:map.get(p.next);
//             node.random=(p.random == null)? null:map.get(p.random);
//             p=p.next;
//         }
//         //返回新的链表头结点
//         return map.get(pHead);
//     }
    public RandomListNode Clone(RandomListNode pHead)
    {
        if(pHead==null) return null;
        RandomListNode p=pHead;
        //先将所有节点复制一遍,插入在当前节点的右侧
        while( p != null){
            RandomListNode node=new RandomListNode(p.label);
            node.next=p.next;
            p.next=node;
            p=node.next;
        }
        //再遍历一遍,处理好左右指针问题问题
        p=pHead;
        while( p != null){
            if(p.random !=null){
                p.next.random=p.random.next;
            }
            p=p.next.next;
        }
        //分离出复制的链表
        p=pHead;
        RandomListNode ans=p.next;
        while( p != null){
            RandomListNode tmp=p.next;
            p.next=tmp.next;
            if(tmp.next != null){//如果tmp.next为空,则证明走到头了
                tmp.next=tmp.next.next;
            }
            p=p.next;
        }
        return ans;
    }
}