Leetcode Copy List with Random Pointer(面试题推荐)

举报
xindoo 发表于 2022/04/16 01:18:19 2022/04/16
【摘要】 给大家推荐一道leetcode上的面试题,这道题的具体讲解在《剑指offer》的P149页有思路讲解,如果你手头有这本书,建议翻阅。 题目链接 here A linked list is given such that each node contains an additional random pointer which co...

给大家推荐一道leetcode上的面试题,这道题的具体讲解在《剑指offer》的P149页有思路讲解,如果你手头有这本书,建议翻阅。

题目链接 here

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.

RandomList中,每个节点不光有一个next指针,而且每个链表节点都有一个random指针,随机指向链表中的一个节点,让你复制这个链表,节点的C++定义如下。


  
  1. /**
  2. * Definition for singly-linked list with a random pointer.
  3. * struct RandomListNode {
  4. * int label;
  5. * RandomListNode *next, *random;
  6. * RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
  7. * };
  8. */

     看到这个题目,估计很多人的第一反应是,先把这个单链表复制出来,然后挨个找random指向的节点。仔细想想这样效率很低,复制链表很快,但确定每个节点的random指针就不容易了,用这种方法的话,每找一个random指针,都必须遍历一次链表。时间复杂度O(n^2)。

    可能也有人可能会想到时间换空间的方法,用hash把时间复杂度降到O(n)。

    当然,还有更省时省空间的方法。

     大概思路就是,在原链表的基础上,把每个节点复制一份加的原来节点的后面,然后设置好新节点random指针,在把所有的新节点从原链表中分离出来,构成一个新链表,这个链表就是我们要的原链表的拷贝。

    下面有三个函数,第一个明显就是复制新节点并把其加入到被复制节点的后面。第二个,因为新节点的random指针还是指向旧节点的,要把它指向新节点,很简单,因为每个节点的新节点都是在原来的节点之后的。 第三个函数,把新节点从原链表中抽离,构成一个新链表。

   这种方法的好处就是,时间复杂度只有O(n),而且我们不需要额外的空间。


  
  1. class Solution {
  2. public:
  3. void CloneNode(RandomListNode *head) {
  4. RandomListNode * p = head;
  5. while (NULL != p) {
  6. RandomListNode * CloneNode = new RandomListNode(p->label);
  7. CloneNode->next = p->next;
  8. CloneNode->random = p->random;
  9. p->next = CloneNode;
  10. p = CloneNode->next;
  11. }
  12. }
  13. void ConnectRandomNode(RandomListNode * head) {
  14. RandomListNode * p = head;
  15. while (NULL != p) {
  16. RandomListNode *pclone = p->next;
  17. if (NULL != pclone->random) {
  18. pclone->random = pclone->random->next;
  19. }
  20. p = pclone->next;
  21. }
  22. }
  23. RandomListNode *copyRandomList(RandomListNode *head) {
  24. if (NULL == head)
  25. return head;
  26. CloneNode(head);
  27. ConnectRandomNode(head);
  28. RandomListNode *pnode = head;
  29. RandomListNode *pclonehead = pnode->next;
  30. RandomListNode *pclonenode = pnode->next;
  31. while (NULL != pnode) {
  32. pnode->next = pclonenode->next;
  33. pnode = pnode->next;
  34. if (NULL != pnode){
  35. pclonenode->next = pnode->next;
  36. pclonenode = pclonenode->next;
  37. }
  38. }
  39. return pclonehead;
  40. }
  41. };


文章来源: xindoo.blog.csdn.net,作者:xindoo,版权归原作者所有,如需转载,请联系作者。

原文链接:xindoo.blog.csdn.net/article/details/38311479

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。