描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针random指向一个随机节点),请对此链表进行深拷贝,并返回拷贝后的头结点。(注意:新链表不能指向原链表节点)。
下图是一个含有5个结点的复杂链表。图中实线箭头表示next指针,虚线箭头表示random指针。为简单起见,指向null的指针没有画出。
思路1:使用Map
- 使用Map存储旧链表节点和新链表节点的映射
Map<RandomListNode, RandomListNode>
- 再次遍历,给新链表节点的next和random赋值
public class Solution {
public RandomListNode Clone(RandomListNode pHead) {
Map<RandomListNode, RandomListNode> map = new HashMap<>();
RandomListNode p1 = pHead;
while(p1 != null) {
map.put(p1, new RandomListNode(p1.label));
p1 = p1.next;
}
p1 = pHead;
while(p1 != null) {
RandomListNode node = map.get(p1);
node.next = map.get(p1.next);
node.random = map.get(p1.random);
p1 = p1.next;
}
return map.get(pHead);
}
}
思路2:复制节点,再拆分
- 遍历在原链表上复制节点
- 再次遍历给random赋值
- 再拆分两个链表
1->2->3
复制之后变为1->1'->2->2'->3->3'
public class Solution {
public RandomListNode Clone(RandomListNode pHead) {
if(pHead == null) {
return null;
}
RandomListNode p1 = pHead;
//修改原链表,复制每一个节点
while(p1 != null) {
RandomListNode node = new RandomListNode(p1.label);
node.next = p1.next;
p1.next = node;
p1 = node.next;
}
p1 = pHead;
//给新节点的random赋值
while(p1 != null) {
if(p1.random != null) {
p1.next.random = p1.random.next;
}
p1 = p1.next.next;
}
p1 = pHead;
RandomListNode ret = pHead.next;
RandomListNode p2 = p1.next;
//拆分链表
while(p2.next != null) {
p1.next = p1.next.next;
p2.next = p2.next.next;
p1 = p1.next;
p2 = p2.next;
}
//将旧链表与新链表断开
p1.next = null;
return ret;
}
}
思路3:暴力破解
- 先遍历创建新链表,random指向原链表节点
- 同时遍历新链表和旧链表,找到对应的random节点
- 给新链表的每个节点random赋值
public class Solution {
public RandomListNode Clone(RandomListNode pHead) {
if (pHead == null) {
return null;
}
RandomListNode p1 = pHead;
RandomListNode ret = new RandomListNode(pHead.label);
RandomListNode p2 = ret;
p2.random = p1.random;
//创建新链表,random指向原链表
while(p1.next != null) {
p1 = p1.next;
p2.next = new RandomListNode(p1.label);
p2 = p2.next;
p2.random = p1.random;
}
p2 = ret;
//遍历新链表
while(p2 != null) {
p1 = pHead;
RandomListNode tmp = ret;
//同时遍历两个链表,找到原链表中的random节点,此时也找到了新链表中对应的节点
while(p2.random != p1) {
p1 = p1.next;
tmp = tmp.next;
}
p2.random = tmp;
p2 = p2.next;
}
return ret;
}
}