题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
方法一
【解题思路】
原链表:A-B-C
1.在原结点后面复制一个结点,主要复制next域
A-B-C 变为A-A’-B-B’-C-C’
以A‘复制A为例:
当前结点p不为空,循环
新建结点m ,值域为A
结点n,存储当前p下一个结点,即B
p的下一个结点为m,即A-A’
m的下一个结点为n,即A-A’-B-C
2.复制random
假设A与C相连,复制后,A’与C’相连
当前链表为 A-A’-B-B’-C-C’
以A’复制A的random为例
p初始化为 链表第一个结点,即p = pHead
当前结点p不为空,循环
此时p为A,p.next为A’
判断p.random (A的random域)是否为空,若不为空,p.next.random(A’的random域)=p.random.next(即A的random域—C的下一个C’)
p向后移动两个结点 p=p.next.next
3.将链表拆开 A-B-C和A‘-B’-C‘
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
//特殊情况:链表为空
if(pHead == null){
return null;
}
//在每个结点后面复制一个结点,复制next域,原:A-B-C,现A-A'-B-B'-C-C'
RandomListNode p = pHead; //p为当前结点
//以A’复制为例
RandomListNode n = p.next;
while(p!=null){
RandomListNode m = new RandomListNode(p.label);//新建结点A'
n = p.next;//将p(A)的下一个结点先保存,即保存B
p.next = m; //A和A'相连
m.next = n; //A'和B相连
p = n;
}
//复制random域
p = pHead;
while(p!=null){
if(p.random!=null){
p.next.random = p.random.next;
}
else
p.next.random = null;
p = p.next.next;
}
//将链表拆开
p = pHead;//p初始化为pHead
RandomListNode h = pHead.next;//复制后新链表 的头节点
while(p!=null){
//以A-A'-B-B'-C-C'为例,此时p为A,S为A'
RandomListNode s = p.next;
//A-B
p.next = s.next;
//若B不为空,A'-B'
if(s.next!=null){
s.next = s.next.next;
}
else
s.next = null;
//p移动为B
p = p.next;
}
return h;
}
}
方法二
浅谈Map map = new HashMap()
Java 中Map map = new HashMap()与HashMap map = new HashMap()区别
Map <数据类型1,数据类型2> map = new HashMap<>();
key - value 映射
放入数据 map.put(key,value);
读取value数据 map.get(key)
本题中,将原链表结点(key)与复制后的链表结点(value)进行映射
-
先将原链表结点与新链表结点(结点需要新建)进行映射,主要复制值,此时新链表结点只有data,next和random域为空
map.put(cur,p) -
给新链表结点 next 域和 random 域赋值
用map.get(cur.next)
注意:判断链表为空
判断 next 和 random 是否为空
/*
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)
{
if(pHead==null)
return null;
Map <RandomListNode,RandomListNode> map = new HashMap<>();
RandomListNode cur = pHead;//当前结点
//建立原结点到复制结点之间的映射,复制值域
while(cur!=null){
RandomListNode p = new RandomListNode(cur.label);
map.put(cur,p);
cur = cur.next;
}
//复制next域和random域
cur = pHead;
while(cur!=null){
RandomListNode s = map.get(cur);
if(cur.next!=null)
s.next = map.get(cur.next);
else
s.next = null;
if(cur.random!=null){
s.random = map.get(cur.random);
}
else
s.random = null;
cur = cur.next;
}
//返回新链表头节点
cur = pHead;
return map.get(cur);
}
}