題意:深拷貝一個鏈表,鏈表除了含有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));
}
}