题目:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空
——来源于《剑指offer》
- 利用哈希表
import java.util.*;
/**
* @author lijing
* @date 2019-08-02 10:18
* @description 克隆复杂链表
*/
public class Solution {
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
private Map<RandomListNode, RandomListNode> map = new HashMap<>();
public RandomListNode Clone(RandomListNode pHead) {
if (pHead == null) {
return null;
}
RandomListNode oldListTemp = pHead;
// 复制头结点
RandomListNode newList = new RandomListNode(oldListTemp.label);
RandomListNode newListTemp = newList;
// 头结点放入哈希表
map.put(oldListTemp, newListTemp);
oldListTemp = oldListTemp.next;
// 循环复制链表数据,并把对应关系放入哈希表
while (oldListTemp != null) {
newListTemp.next = new RandomListNode(oldListTemp.label);
newListTemp = newListTemp.next;
map.put(oldListTemp, newListTemp);
oldListTemp = oldListTemp.next;
}
newListTemp = newList;
oldListTemp = pHead;
while (newListTemp != null) {
newListTemp.random = map.get(oldListTemp.random);
newListTemp = newListTemp.next;
oldListTemp = oldListTemp.next;
}
return newList;
}
}
- 不用辅助空间
- 将链表中每个节点复制一份放在该结点的后面位置
2. 修改结点的特殊指针
3. 将链表拆开
/**
* @author lijing
* @date 2019-08-02 10:18
* @description 克隆复杂链表
*/
public class Solution2 {
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
public RandomListNode Clone(RandomListNode pHead) {
if (pHead == null) {
return null;
}
cloneNodes(pHead);
connectSiblingNodes(pHead);
return reconnectNodes(pHead);
}
private RandomListNode reconnectNodes(RandomListNode pHead) {
RandomListNode pCloneHead = pHead.next;
RandomListNode pClone = pHead.next;
RandomListNode p = pHead;
while (p.next.next != null) {
p.next = pClone.next;
p = p.next;
pClone.next = p.next;
pClone = pClone.next;
}
p.next = null;
return pCloneHead;
}
private void connectSiblingNodes(RandomListNode pHead) {
RandomListNode p = pHead;
while (p != null) {
if (p.random != null) {
p.next.random = p.random.next;
}
p = p.next.next;
}
}
private void cloneNodes(RandomListNode pHead) {
RandomListNode p = pHead;
while (p != null) {
RandomListNode randomListNode = new RandomListNode(p.label);
randomListNode.next = p.next;
p.next = randomListNode;
p = randomListNode.next;
}
}
}