题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
题目解析
这个题目主要的难点在于随机指向的这个节点如何去复制到另一个链表中去,那么,这里如果单纯的采用直接赋值拷贝的方式肯定是不可取的,因为这个方式的话需要遍历整个链表确定每个元素指向了第几个元素然后再次扫描并进行修改指向,这当然肯定不是最好的解决办法。
解题思路
既然要复制,那么平行的将每个元素复制一份作为一个拷贝,作为其原来元素的next插入到原来的链表中去,这样的话就形成了,A->A`->B->B`的链表,那么,在复制的过程中我们可以同时拷贝A的random来记录其random指向,注意random可以在后面做向后移动一个元素的方式进行获取。
所以这个题分两个步骤,
1.复制所有元素并将其添加为原来元素的next节点,同时复制random指向。
2.删除链表中原来的节点,将新的节点取出来,并且,链表中的random和next全部向后面平移一位。
代码实现
/*
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;
}
RandomListNode node = pHead;
while(node != null) {
RandomListNode nodeCopy = new RandomListNode(node.label);
nodeCopy.next = node.next;
nodeCopy.random = node.random;
node.next = nodeCopy;
node = node.next.next;
}
node = pHead;
int count = 0;
RandomListNode head = null;
RandomListNode temp = null;
while(node != null) {
if(count % 2 == 1) {
if(count == 1) {
head = node;
}
if(node.random != null) {
node.random = node.random.next;
}
temp = node.next;
if(node.next != null) {
node.next = node.next.next;
}
node = temp;
} else {
node = node.next;
}
count ++;
}
pHead.next = null;
return head;
}
}