思路一:模拟
可以首先定义两个集合,一个集合用来存储原链表,一个集合用来存储现链表
先将现链表创造结点然后填入原链表的结点值,之后指向与原链表一致,操作在现链表而不是指向原链表。
之后,再处理next指针,i结点指向i+1结点即可。
最终,就是random指针,我们可以用集合的indexOf来判断指向结点的下标,然后指向即可。
/*
// 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;
List<Node>list=new ArrayList<Node>();
List<Node>jie=new ArrayList<Node>();
Node tmp=head;
int len=0;
while(tmp!=null){
len++;
list.add(tmp);
tmp=tmp.next;
}
for(int i=0;i<len;i++){
jie.add(new Node(-1));
jie.get(i).val=list.get(i).val;
}
for(int i=0;i<len;i++){
if(i==len-1){
jie.get(i).next=null;
}
else{
jie.get(i).next=jie.get(i+1);
}
if(list.get(i).random!=null)
jie.get(i).random=jie.get(list.indexOf(list.get(i).random));
else
jie.get(i).random=null;
}
return jie.get(0);
}
}
思路二:哈希表+模拟。这里其实也可以用哈希表进行记录,同时在遍历原链表的时候创建新的结点,不必要创建集合,这样可以减少一些空间复杂度。
/*
// 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;
Map<Node,Node>map=new HashMap<Node,Node>();
Node dummy=new Node(-1);
Node tmp=head;
Node ha=dummy;
while(tmp!=null){
Node node=new Node(tmp.val);
map.put(tmp,node);
ha.next=node;
ha=ha.next;
tmp=tmp.next;
}
Node t=dummy.next;
Node li=head;
while(t!=null){
t.random=map.get(li.random);
t=t.next;
li=li.next;
}
return dummy.next;
}
}