题目描述:
注意:本题中的复制指的是深拷贝,也就是要返回一个全新的链表,且最终原链表的状态不能改变。
思路解析:
方法一:哈希表(HashMap)
遍历一遍原链表,以原链表中的
老节点为Key,以老节点的深拷贝为value,以此存入map中,如图:
再遍历一遍原链表,将
每个新节点按原链表中对应的老节点的next、random的顺序连接,最后组成一个新链表,返回新链表的头节点即可,如图所示:
方法二:插入法(不使用额外API)
将每个复制节点插入对应的老节点的后面,如图所示:
然后
按原链表中老节点的next、random的连接顺序将复制节点依次连接成新链表即可。注意保持原链表的状态不变。(连好的图有些复杂,这里就不作图示了)
伪代码:
方法一:哈希表(HashMap)
package 苟熊岭熊哒;
import java.util.HashMap;
class Solution {
public Node copyRandomList(Node head) {
if(head==null){
return null;
}
HashMap<Node,Node> map=new HashMap<>();
//哈希表,Key存老结点,Value存新结点
Node cur=head;//复杂头结点
//遍历一遍老链表,存值
while(cur!=null){
map.put(cur,new Node(cur.val));
//存入新结点
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);
}
}
测试结果:
方法二:插入法(不使用额外API)
package 苟熊岭熊哒;
class Solution {
public Node copyRandomList(Node head) {
if(head==null){
return null;//链表为空时,直接返回空指针
}
Node cur=head;//复制原链表头节点的位置
Node Next=null;
//第一遍遍历--将每个新结点放到对应旧结点的后面
while(cur!=null){
Next=cur.next;
cur.next=new Node(cur.val);//创建新节点
cur.next.next=Next;
cur=Next;
}
//第二遍遍历--设置每个新结点的random
cur=head;
Node curCopy=null;//表示新链表的节点(旧节点的复制)
while(cur!=null){
Next=cur.next.next;//表示旧节点的位置
curCopy=cur.next;//表示旧节点的复制
//↓注意原链表的random可能为空指针
curCopy.random=cur.random==null?null:cur.random.next;
cur=Next;
}
//第三遍遍历--将每个新结点连成一条完整的新链表
cur=head;
Node newHead=head.next;//新链表的头节点
while(cur!=null){
Next=cur.next.next;//表示旧节点的位置
curCopy=cur.next;//表示旧节点的复制
cur.next=Next;//保持原链表的连接状态不变
curCopy.next=Next==null?null:Next.next;//Next为空时,表示Next此时为尾节点
cur=Next;
}
return newHead;//返回新链表的头节点
}
}
测试结果:
这道题的介绍到这里就结束了,如果你觉得本篇文章对你多少有些帮助,可以点个赞或者收藏一波支持支持,欢迎各位大佬批评指正,咱们下次再见!