题意:深拷贝一个链表,链表除了含有next指针外,还包含一个random指针,该指针指向字符串中的某个节点或者为空。
节点定义为:
// Definition for singly-linked list.
public class RandomListNode {
int label;
RandomListNode next, random;
RandomListNode(int x) { this.label = x; }
}
假设原始链表如下,细线表示next指针,粗线表示random指针,没有画出的指针均指向NULL:
该题有一种巧妙地解法,记住即可。构建新节点时,指针做如下变化,即把新节点插入到相应的旧节点后面:
分两步
1、构建新节点random指针:new1->random = old1->random->next, new2-random = NULL, new3-random = NULL, new4->random = old4->random->next
2、恢复原始链表以及构建新链表:例如old1->next = old1->next->next, new1->next = new1->next->next
该算法时间复杂度O(N),空间复杂度O(1)
/**
* Definition for singly-linked list with a random pointer.
* class RandomListNode {
* int label;
* RandomListNode next, random;
* RandomListNode(int x) { this.label = x; }
* };
*/
class Solution {
public static RandomListNode copyRandomList(RandomListNode head) {
if(head == null) return null;
RandomListNode fastNode = head;
while(fastNode != null){
RandomListNode insertNode = new RandomListNode(fastNode.label);
insertNode.next = fastNode.next;
fastNode.next = insertNode;
fastNode = fastNode.next.next;
}
fastNode = head;
while(fastNode != null){
if(fastNode.random != null){
fastNode.next.random = fastNode.random.next;
}
fastNode = fastNode.next.next;
}
fastNode = head;
RandomListNode newHead = head.next;
while(fastNode != null){
RandomListNode newNode = fastNode.next;
fastNode.next = newNode.next;
if(newNode.next != null){
newNode.next = newNode.next.next;
}
fastNode = fastNode.next;
}
return newHead;
}
public static void print(RandomListNode head){
while(head != null){
System.out.println(head.label);
head = head.next;
}
}
public static void main(String[] args) {
RandomListNode l1 = new RandomListNode(1);
RandomListNode l2 = new RandomListNode(2);
RandomListNode l3 = new RandomListNode(3);
RandomListNode l4 = new RandomListNode(4);
l1.next = l2;
l2.next = l3;
l3.next = l4;
l1.random = l3;
l4.random = l2;
print(copyRandomList(l1));
}
}