JZ25 - 复杂链表的复制
题目:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
解题思路:复制节点连接到原节点的后面,这样就能时刻找到原节点的复制节点,方便对random指针调整时使用。最后分离原节点和新节点,即偶数节点的连接为当前复制的链表。
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
/**
* @author 枫叶火火
*/
public class Solution {
public RandomListNode Clone(RandomListNode pHead)
{
if(pHead == null){
return null;
}
//复制节点
copyNode(pHead);
//复制random的指针
copyRandom(pHead);
//取到第一个新复制节点
RandomListNode root = pHead.next;
//进行新旧分离
partNode(pHead, root);
return root;
}
//复制当前节点进行插入,最后组成一个原节点一个复制节点的连接
private void copyNode(RandomListNode node){
if(node == null){
return;
}
//复制当前节点
RandomListNode c = new RandomListNode(node.label);
//进行插入
c.next = node.next;
node.next = c;
//复制插入下一节点
copyNode(c.next);
}
//对复制节点的random进行赋值
private void copyRandom(RandomListNode node){
if(node == null){
return;
}
//判断当前节点的random是否是null
if(node.random != null){
//下一个节点也就是复制节点的random 等于 当前节点的random的下一个(random的复制节点)
node.next.random = node.random.next;
}
//处理下一个节点
copyRandom(node.next.next);
}
//分离原链表和新复制的链表
private void partNode(RandomListNode node, RandomListNode newNode){
if(node == null){
return;
}
//根据之前连接的链表,下一个原节点等于新节点的下一个
node.next = newNode.next;
//调整当前原节点
node = node.next;
//下一个新节点为当前原节点的下一个
newNode.next = node == null ? null : node.next;
//进行下一个节点的处理
partNode(node,newNode.next);
}
}