题目描述:
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
示例 1:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
示例 2:
输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
示例 3:
输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]
示例 4:
输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null。
解题思路:
这道题的思路很巧妙,我的感觉是,他给的数据中每个都有两个数据,而第二个数就是迷惑人的,这个数据没有任何作用,也无法用代码求出这个数据
因此解题的时候需要用其他的方法替代出这个数据:
- 先将每一个节点复制一遍,放在本节点的后面
- 此时根据原链表中每个节点的random,求出复制的节点的random。(这一步是关键)
- 将复制的节点分离出来返回
第一步和第三步就不用说了,这里解释一下第二步怎样求得,因为几乎是完全复制出来的新节点,所以新复制节点y的random就是原节点x的random的next;
如上图所示,如果B的random指向A,那么B1的random肯定是指向A1;
A1的求法就是B->random->next也就是B1->random的值。
代码:
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if(!head) return NULL;
Node *headx = head;
//将每个节点复制到他后面
while(headx)
{
auto x = new Node(headx->val);
x->next = headx->next;
headx->next = x;
headx = x->next;
}
//将另一个指针也复制一次
Node *heady = head;
while(heady && heady->next)
{
if(heady->random)
heady->next->random = heady->random->next;
heady = heady->next->next;
}
//将两个分离
Node *newhead = head->next;
Node *headz = head;
while(headz && headz->next)
{
Node *z = headz->next;
headz->next = z->next;
headz = z;
}
return newhead;
}
};