链表--复制含有随机指针节点的链表
一种特殊的链表节点类描述如下:
public class Node { public int value; public Node next;
public Node rand;
public Node(int data) { this.value = data; }
}
Node类中的value是节点值, next指针和正常单链表中next指针的意义一 样, 都指向下一个节点,
rand指针是Node类中新增的指针, 这个指针可 能指向链表中的任意一个节点, 也可能指向null。
给定一个由Node节点类型组成的无环单链表的头节点head,
请实现一个 函数完成这个链表中所有结构的复制, 并返回复制的新链表的头节点。
进阶:不使用额外的数据结构, 只用有限几个变量, 且在时间复杂度为 O(N)内完成原问题要实现的函数。
利用HashMap<Node, Node>将head节点均保存进去,key是head的结点,value是相应节点复制的新节点
然后遍历Map,将对应的rand结点找出来相连接
public static Node copyRandom1(Node head){
if(head == null || head.next == null) return head;
Map<Node, Node> map = new HashMap<>();
Node node = head;
while(node != null){
map.put(node, new Node(node.val));
node = node.next;
}
node = head;
while(node != null){
map.get(node).next = node.next;
map.get(node).rand = node.rand;
node = node.next;
}
return map.get(head);
}
解法二:将next结点先链接在node结点之后,然后将遍历的时候,将node结点的rand作为线索
然后将node.next的rand找到指向,最后再将两个链表分开即可。
public static Node copyRandom2(Node head){
if(head == null || head.next == null) return head;
Node node = head;
while(node != null){
Node nextNode = node.next;
node.next = new Node(node.val);
node.next.next = nextNode;
node = nextNode;
}
node = head;
while(node != null){
node.next.rand = node.rand;
node = node.next.next;
}
node = head;
Node newHead = node.next;
while(node != null){
Node nextNode = node.next.next;
Node node1 = node.next;
node.next = nextNode;
node1.next = nextNode != null ? nextNode.next : null;
node = nextNode;
}
return newHead;
}

浙公网安备 33010602011771号