题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
题解一
使用哈希表保存原链表和复制后链表的指针。
- 第一个遍历将原链表的next指针复制一遍,同时保存对应的指针(确保原链表中的每一个节点都能在复制后链表中找到)。
- 第二个遍历将原链表的random指针复制一遍(从哈希表中取对应节点)。
时间复杂度为O(n),空间复杂度为O(n)。
public RandomListNode Clone(RandomListNode head) {
if (head == null)
return null;
RandomListNode headClone = new RandomListNode(head.label);
HashMap<RandomListNode, RandomListNode> map = new HashMap<>();
map.put(head, headClone);
// 第一个遍历复制next指针
RandomListNode p = head.next;
RandomListNode pClone = headClone;
while (p != null) {
pClone.next = new RandomListNode(p.label);
pClone = pClone.next;
map.put(p, pClone);
p = p.next;
}
// 第二个遍历复制random指针
p = head;
pClone = headClone;
while (p != null) {
if (p.random != null)
pClone.random = map.get(p.random);
p = p.next;
pClone = pClone.next;
}
return headClone;
}
题解二
- 在原链表的每个节点后都添加一个节点作为复制后的节点。
- 给复制后的节点添加random指针。
- 把第二步得到的链表拆分成两个链表。
时间复杂度为O(n),空间复杂度为O(1)。
public RandomListNode Clone(RandomListNode head) {
if (head == null)
return null;
// 1.在原链表的每个节点后都添加一个节点作为复制后的节点。
RandomListNode p = head;
RandomListNode r;
while (p != null) {
r = new RandomListNode(p.label);
r.next = p.next;
p.next = r;
p = r.next;
}
// 2.添加random指针。
p = head;
while (p != null) {
if (p.random != null)
p.next.random = p.random.next;
p = p.next.next;
}
// 3.拆分两个链表。
p = head;
r = head.next;
RandomListNode headClone = r;
while (p != null) {
p.next = p.next.next;
if (r != null && r.next != null)
r.next = r.next.next;
p = p.next;
r = r.next;
}
return headClone;
}
网友评论