目录
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,请不要返回参数中的节点引用) 复制链表如下图:
复杂节点定义如下:
public class ComplexListNode {
int value;
ComplexListNode next;
ComplexListNode random;
public ComplexListNode(int value) {
this.value = value;
}
}
测试用例
- 功能测试(节点中的random指向节点自身;两个节点的random形成环状结构;链表中只有一个节点)
- 特殊输入测试(指向链表头结点的指针为空指针)
题目考点
- 考察应聘者对复杂问题的思维能力。
- 考察应聘者分析时间效率和空间效率的能力。
解题思路
1、在每个节点的后面插入复制的节点,如下图:
2、对复制的节点的random指针进行赋值,如下图:
3、将上面的链表拆成两个链表,原始链表和复制链表,如下图:
参考解题
/*
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;
}
// 三步
CloneNode(pHead);
ConnectRandomNodes(pHead);
return ReconnectNodes(pHead);
}
// 1、复制N'到N后面,插入新节点
public void CloneNode(RandomListNode pHead){
RandomListNode CurrentNode = pHead;
while(CurrentNode != null){
RandomListNode pCloned = new RandomListNode(CurrentNode.label);
// 克隆
pCloned.next = CurrentNode.next;
pCloned.random = null;
// 插入克隆节点
CurrentNode.next = pCloned;
// 继续遍历
CurrentNode = pCloned.next;
}
}
// 2、设置复制出来节点的random指针
public void ConnectRandomNodes(RandomListNode pHead){
RandomListNode CurrentNode = pHead;
while(CurrentNode != null){
RandomListNode pCloned = CurrentNode.next;
if(CurrentNode.random != null){
// 设置random指针
pCloned.random = CurrentNode.random.next;
}
// 遍历
CurrentNode = pCloned.next;
}
}
// 3、拆分成两个链;
public RandomListNode ReconnectNodes(RandomListNode pHead){
RandomListNode CurrentNode = pHead;
RandomListNode ClonedHead = pHead.next;
// 取偶数部分
while(CurrentNode.next != null){
RandomListNode next = CurrentNode.next;
CurrentNode.next = next.next;
// 遍历
CurrentNode = next;
}
return ClonedHead;
}
}