JZ25-复杂链表的复制
题目:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)。
示例:
输入:{1,2,3,4,5,3,5,#,2,#}
输出:{1,2,3,4,5,3,5,#,2,#}
/*
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) {
int n=0;
//创建新链表的头节点
RandomListNode cHead = new RandomListNode(0);
//指向新链表结点遍历
RandomListNode list = cHead;
//指向旧链表结点遍历
RandomListNode p = pHead;
RandomListNode pp;
//如果需要复制的链表为空直接返回null
if(pHead == null){
return null;
}
//链表不为空时,依次创建结点复制
while(p!=null){
RandomListNode q = new RandomListNode(p.label);
list.next = q;
list = list.next;
p = p.next;
}
//重新将P指向复制链表的表头,list指向新链表的表头
p = pHead;
list = cHead.next;
while(p!=null){
//n是计算random指向的结点离头节点的位置
n=0;
pp = pHead;
while(p.random!=null){
if(pp!=p.random){
n = n+1;
}else{
break;
}
pp = pp.next;
}
//p.random为空的话直接将list.random也设置为空
if(p.random == null){
list.random = null;
}else{
//p.random不为空的话,依次移动pp指针,让他移动到random处
pp = cHead.next;
while(n>0){
pp = pp.next;
n--;
}
//找到random的位置,改变指针的指向
list.random = pp;
}
list = list.next;
p = p.next;
}
return cHead.next;
}
}
但是需要遍历两遍链表,看了别人用map的方式
import java.util.*;
public class Solution {
public RandomListNode Clone(RandomListNode pHead) {
Map<RandomListNode, RandomListNode> map = new HashMap<>();
RandomListNode cur = pHead;
while (cur != null) {
map.put(cur, new RandomListNode(cur.label));
cur = cur.next;
}
cur = pHead;
while (cur != null) {
map.get(cur).next = map.get(cur.next);
map.get(cur).random = map.get(cur.random);
cur = cur.next;
}
return map.get(pHead);
}
}
将所有的结点存入map中,减少了很多if-else的判断操作。