题目描述
// 35. 复杂链表的复制
// 力扣
// 请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中
// ,每个节点除了有一个 next 指针指向下一个节点,还有一个 ran
// dom 指针指向链表中的任意节点或者 null。
// 牛客
// 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下
// 一个节点,另一个特殊指针random指向一个随机节点),请对此链表进
// 行深拷贝,并返回拷贝后的头结点。(注意,输出结果中请不要返回参
// 数中的节点引用,否则判题程序会直接返回空)
题解
复制结点部分图解:
random指向图解:
// 力扣
// 执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
// 内存消耗:37.5 MB, 在所有 Java 提交中击败了98.32%的用户
/*
// Definition for a Node.
class Node {
int val;
Node next;
Node random;
public Node(int val) {
this.val = val;
this.next = null;
this.random = null;
}
}
*/
class Solution {
public Node copyRandomList(Node head) {
if (head == null)
return null;
// 每一个结点之后插入其复制结点
Node cur = head; // 初始化遍历指针
while (cur != null) {
Node clone = new Node(cur.val); // 复制cur遍历的原链表结点,记为clone
clone.next = cur.next; // clone.next与cur.next一致
cur.next = clone; // 然后让cur.next指向clone本身
cur = clone.next; // 移动cur到下一个原链表结点
}
// 构建random指向
cur = head; // 重置cur回head
while (cur != null) { // 循环遍历链表
// 令clone结点为cur的下一个结点(clone结点即为cur的复制结点)
Node clone = cur.next;
if (cur.random != null) // 如果cur.random不为null
// 由于cur和clone的关系,clone是cur的下一个结点
// clone.random即为cur.random的下一个结点
clone.random = cur.random.next;
cur = clone.next; // cur移动至下一个原链表结点
}
// 两个链表拆分
cur = head; // 重置cur回head
Node cloneHead = head.next; // 设定复制链表的头结点
while (cur.next != null) { // 循环遍历,直到cur.next为空
// 令cur.next为next,到此我们有cur和next(cur.next)双指针
Node next = cur.next;
// 令cur的next直接指向next.next(cur.next.next)
// 原链表cur越过了cur的复制点,连上了原链表cur的下一个结点
cur.next = next.next;
cur = next; // cur右移
}
return cloneHead; // 拆分结束,最后返回复制链表头结点
}
}
// 牛客
// 运行时间:12ms
// 占用内存:9804k
public class Solution {
public RandomListNode Clone(RandomListNode pHead) {
if (pHead == null)
return null;
// 每个结点复制
RandomListNode cur = pHead;
while (cur != null) {
RandomListNode clone = new RandomListNode(cur.label);
clone.next = cur.next;
cur.next = clone;
cur = clone.next;
}
// random指向部署
cur = pHead;
while (cur != null) {
RandomListNode clone = cur.next;
if (cur.random != null)
clone.random = cur.random.next;
cur = clone.next;
}
// 分离
cur = pHead;
RandomListNode cloneHead = pHead.next;
while (cur.next != null) {
RandomListNode next = cur.next;
cur.next = next.next;
cur = next;
}
return cloneHead;
}
}