问题描述
问题链接:https://leetcode-cn.com/problems/fu-za-lian-biao-de-fu-zhi-lcof/
分析
还没有学到哈希,所以官方给的题解不太懂。然后想到了另一种方法。先来分析一下这道题吧。
这道题的关键在于复制随机指针
这题的最大难点就在于复制随机指针,比如下图中
我们可以分为三步来解决。
第一步:根据遍历到的原节点创建对应的新节点,每个新创建的节点是在原节点后面,比如下图中原节点1不再指向原原节点2,而是指向新节点1
第二步是最关键的一步,给新链表的随机指针赋值
上图中,我们可以观察到这么一个规律
所以新结点指向的是原结点的next(这个非常关键)
第三步就简单了,只要将两个链表分离开即可
AC代码
- 解法一
代码如下:
class Solution {
public Node copyRandomList(Node head) {
if(head==null) {
return null;
}
Node p = head;
//第一步,在每个原节点后面创建一个新节点
//1->1'->2->2'->3->3'
while(p!=null) {
Node newNode = new Node(p.val);
newNode.next = p.next;
p.next = newNode;
p = newNode.next;
}
p = head;
//第二步,给新节点的随机节点赋值(连接)
while(p!=null) {
if(p.random!=null) {
p.next.random = p.random.next;
}
p = p.next.next;
}
Node newHead = new Node(-1);
p = head;
Node cur = newHead;
//第三步,分离得到新的单独链表
while(p!=null) {
cur.next = p.next;
cur = cur.next;
p.next = cur.next;
p = p.next;
}
return newHead.next;
}
}
学完hash啦,解法二来啦,hash真的香。
- 解法二
class Solution {
public Node copyRandomList(Node head) {
HashMap<Node,Node> map=new HashMap<>();
Node cur=head;
while(cur!=null)
{
Node node=new Node(cur.val);
map.put(cur,node);
cur=cur.next;
}
cur=head;
while(cur!=null)
{
map.get(cur).next=map.get(cur.next);
map.get(cur).random=map.get(cur.random);
cur=cur.next;
}
return map.get(head);
}
}