leetcode -- Copy List with Random Pointer

A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.

Return a deep copy of the list.

[解题思路]

1.和clone graph那题差不多,使用一个map来保存已经创建好的node。

第一步:先复制原始链表中的节点,用next指针链接起来,在复制节点时放入map中

第二步:设置每个节点的random指针

空间复杂度为O(n),时间复杂度为O(n)

Accepted Code

 1 public RandomListNode copyRandomList(RandomListNode head) {

 2         // Note: The Solution object is instantiated only once and is reused by each test case.

 3         if(head == null){

 4             return head;

 5         }

 6         

 7         Map<RandomListNode, RandomListNode> map = new HashMap<RandomListNode, RandomListNode>();

 8         RandomListNode newHead = new RandomListNode(head.label);

 9         map.put(head, newHead);

10         RandomListNode p1 = head;

11         RandomListNode p2 = newHead;

12         p1 = p1.next;

13         // p2 = p2.next;

14         

15         while(p1 != null){

16             RandomListNode tmp = new RandomListNode(p1.label);

17             p2.next = tmp;

18             map.put(p1, tmp);

19             p1 = p1.next;

20             p2 = p2.next;

21         }        

22         

23         p1 = head;

24         p2 = newHead;

25         while(p1 != null){

26             RandomListNode random = p1.random;

27             if(random != null)

28                 p2.random = map.get(random);

29             p1 = p1.next;

30             p2 = p2.next;

31         }

32        

33         return newHead;

34     }

 

2.上面的做法使用map的意义在于设置random指针时可以直接从map中找到,但使用map会带来O(n)的空间消耗

换个思路:第一步仍然根据原始链表的每个结点n创建相应的n'。将n'链接到n后面

第二步设置n'的random指针。n'的random指针所指向的结点是n的random指针所指向的结点的下一个结点

第三步把第二步得到的链表拆成两个链表

 1 public class Solution {

 2     

 3     public RandomListNode cloneNodes(RandomListNode head){

 4         RandomListNode p1 = head;

 5         while(p1 != null){

 6             RandomListNode c1 = new RandomListNode(p1.label);

 7             c1.next = p1.next;

 8             p1.next = c1;

 9             p1 = c1.next;

10         }

11         return head;

12     }

13     

14     public RandomListNode setRandomPointer(RandomListNode head){

15         RandomListNode p1 = head;

16         while(p1 != null){

17             RandomListNode r1 = p1.random;

18             if(r1 != null){

19                 p1.next.random = r1.next;

20             }

21             p1 = p1.next.next;

22         }

23         return head;

24     }

25     

26     public RandomListNode reconnectNodes(RandomListNode head){

27         RandomListNode cloneHead = head.next;

28         RandomListNode p1 = head;

29         RandomListNode p2 = cloneHead;

30         while(p1 != null && p2 != null){

31             p1.next = p2.next;

32             p1 = p1.next;

33             if(p1 != null){

34                 p2.next = p1.next;

35             }

36             p2 = p2.next;

37         }

38         return cloneHead;

39     }

40     

41     public RandomListNode copyRandomList(RandomListNode head) {

42         // Note: The Solution object is instantiated only once and is reused by each test case.

43         if(head == null){

44             return head;

45         }

46         

47         cloneNodes(head);

48         setRandomPointer(head);

49         return reconnectNodes(head);

50     }

51 }

ATT:拆成两个链表时,当处理到最后一个节点时需要注意

 

 

 
  

你可能感兴趣的:(LeetCode)