题目描述:
https://www.nowcoder.com/practice/f836b2c43afc4b35ad6adc41ec941dba
思路:因为不可以用原来链表中的结点,所以链表里面的每一个节点我们都要重新新建一遍
方法一:使用hash表,首先遍历链表,把节点本身和新建的对应节点都放入map中,然后再一次遍历链表,并从hash表中取出对应的值
res链表为返回的结果
p为进行复制的链表
pHead作为放入map的数据
head作为第二次遍历链表的头结点
方法二:双指针法
把每一个节点复制并且插入原来的链表中,即原来1-2-3变成1-1(拷贝)-2-2(拷贝)-3-3(拷贝)
然后再次遍历链表把对应的random指针也进行拷贝
最后再次遍历链表将链表拆成两个链表即可
1.hashmap
import java.util.HashMap;
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
// 方法一 hashmap
// 如果只保存random到map表里面会报错
// wrong,cannot used original node of list
public class Solution {
public RandomListNode Clone(RandomListNode pHead) {
if(pHead==null) return pHead;
HashMap<RandomListNode,RandomListNode> map=new HashMap<>();
RandomListNode res=new RandomListNode(pHead.label);
RandomListNode p=res;
RandomListNode head=pHead;
while(pHead!=null){
map.put(pHead,new RandomListNode(pHead.label));
pHead=pHead.next;
}
while(head!=null){
p.next=map.get(head.next);
p.random=map.get(head.random);
p=p.next;
head=head.next;
}
return res;
}
}
2.双指针
import java.util.HashMap;
/*
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 pHead;
RandomListNode head=pHead;
RandomListNode h=pHead;
// 复制
while(pHead!=null){
RandomListNode clone=new RandomListNode(pHead.label);
clone.next=pHead.next;
pHead.next=clone;
pHead=clone.next;
}
// 复制random
RandomListNode clone=head.next;
while(head!=null){
if(head.random==null){
clone.random=null;
}
else{
clone.random=head.random.next;
}
head=head.next.next;
if(clone.next!=null){ //要检查,因为拷贝的下一个可能就是null,而null没有next,如果不检查就会报错
clone=clone.next.next;
}
}
//拆分
clone=h.next;
RandomListNode res=clone;
while(h!=null){
h.next=h.next.next;
h=h.next;
if(clone.next!=null){
clone.next=clone.next.next;
}
clone=clone.next;
}
return res;
}
}