1、题目描述
方法一:使用哈希表
2、算法分析
本题是复杂链表的复制:
普通链表都是next指针指向后面的链表,现在的是两个指针next,random指针指向后面结点,random是随机指针方向
步骤如下:
使用Map集合进行映射,key是当前链表的结点,value是新链表的结点
①链表结点的复制,建立“原结点——>新结点”的映射
②构建新链表结点的next,random指针方向
③返回新链表结点的头结点
如图:
3、代码实现
/*
// 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;
}
}
*/
import java.util.*;
// 使用 Map ,key存储的是原链表结点,value存储的是新链表的结点
class Solution {
public Node copyRandomList(Node head) {
if(head == null){
return null;
}
Node cur = head;
Map<Node,Node> map = new HashMap<>();
// 1.复制各结点,建立“原结点-->新结点”的映射
while(cur != null){
map.put(cur,new Node(cur.val));
cur = cur.next;
}
// 2.构建新链表 next和random的方向
// 结点有2个指针,一个是next,一个是random指针
cur = head;
while(cur != null){
map.get(cur).next = map.get(cur.next);
map.get(cur).random = map.get(cur.random);
cur = cur.next;
}
// 3. 返回新链表的头结点,key对应的值value,对应新的链表
return map.get(head);
}
}
方法二:使用复制拆分
具体看代码
把RandomListNode 修改成Node;label修改成val即可
/*
public class RandomListNode {
int label;
RandomListNode next = null;
RandomListNode random = null;
RandomListNode(int label) {
this.label = label;
}
}
*/
// 1.复制链表复制每个结点,复制结点A得到A1,将A1插到结点A后面
// 2.重新遍历链表,复制原链表的随机指针random指向的结点到新结点,A1.next = A.random.next
// 3.拆分链表,将链表拆分为原链表和复制后的链表
import java.util.*;
public class Solution {
public RandomListNode Clone(RandomListNode pHead) {
if(pHead == null){
return null;
}
RandomListNode currentNode = pHead;
// 1、插入新结点,cloneNode是复制的结点,结点A得到A1,将结点A1插到结点A后面
while(currentNode != null){
// 创建一个
RandomListNode cloneNode = new RandomListNode(currentNode.label);
RandomListNode nextNode = currentNode.next;
currentNode.next = cloneNode;
cloneNode.next = nextNode;
currentNode = nextNode;
}
currentNode = pHead;
// 2、 重新遍历链表,复制原来结点的随机指针给新结点
while(currentNode != null){
currentNode.next.random = currentNode.random == null?null:currentNode.random.next;
currentNode = currentNode.next.next;
}
// 拆分链表,将链表拆分为原链表和复制后的链表
currentNode = pHead;
RandomListNode pCloneHead = pHead.next;
while(currentNode != null){
RandomListNode cloneNode = currentNode.next;
currentNode.next = cloneNode.next;
cloneNode.next = cloneNode.next == null?null:cloneNode.next.next;
currentNode = currentNode.next;
}
return pCloneHead;
}
}