• [Leetcode]138. 复制带随机指针的链表


    目录

    1.题目链接

    2.1解法①(暴力)

    2.1.1解法思路:

    2.1.2代码实现:

    2.2解法②(进阶)

    2.1.1解法思路:

    2.2.2代码实现:


    1.题目链接

    138. 复制带随机指针的链表 - 力扣(LeetCode)

    2.1解法①(暴力)

    2.1.1解法思路:

    时间复杂度:O(N^2) 空间复杂度O(N); 

    ①先遍历原链表,复制出一个一模一样的单链表,先不管random的问题;

    ②然后再遍历新生成的链表,同时进行random指针的拷贝:

    这个实现是对于新生成的每一个节点,然后找到原链表的对应的节点,然后遍历原链表找出原链表对应的random指针指向的节点,计算random指向的节点和原链表中对应的节点的相对位置i;

    然后在新生成的单链表中找到相同相对位置的节点,然后再将新生成的单链表中的该节点的random指向这个相对位置对应的节点。

    2.1.2代码实现:

    1. struct Node* BuyNode(int x)
    2. {
    3. struct Node* New = (struct Node*)malloc(sizeof(struct Node));
    4. New->val = x;
    5. New->next = NULL;
    6. New->random = NULL;
    7. return New;
    8. }
    9. int CheckList(struct Node* head, struct Node*cur)
    10. {
    11. int x = 0;
    12. while(cur->random != head)
    13. {
    14. head = head->next;
    15. x++;
    16. }
    17. return x;
    18. }
    19. struct Node* copyRandomList(struct Node* head)
    20. {
    21. struct Node* cur = head;
    22. struct Node* temp = BuyNode(-1);
    23. struct Node* pre = temp;
    24. //先复制单链表
    25. while(cur)
    26. {
    27. temp->next = BuyNode(cur->val);
    28. temp = temp->next;
    29. cur = cur->next;
    30. }
    31. //复制随机指针
    32. //1遍历原链表,遇到随即指针不为空的节点;
    33. //2然后再遍历链表找到随即指针指向的节点,计算位置;
    34. //3然后放入新的链表中
    35. temp = pre->next;//初始化新链表箭头
    36. cur = head;//初始化旧链表指针
    37. while(cur)
    38. {
    39. if(cur->random != NULL)
    40. {
    41. int x = CheckList(head, cur);
    42. struct Node* shead = pre->next;
    43. for(int i = 0; i < x; i++)
    44. {
    45. shead = shead->next;
    46. }
    47. temp->random = shead;
    48. }
    49. cur = cur->next;
    50. temp = temp->next;
    51. }
    52. return pre->next;
    53. }

    2.2解法②(进阶)

    2.1.1解法思路:

    ①先进行如下的操作:

    在每个节点后面插入一个新的节点然后每个节点的val和前一个节点相同;

     ②然后要做的就是处理新插入节点的random指针,进行第一步的操作就是为了方便第二步来处理random指针的:具体实现的方法就是给定一个指针cur来遍历原来就有的节点,然后遇到random指针不为空的节点,然后就将其next的random指向其的random的next即可;

    (这个是最关键的)实现如下的效果;

     ③第三步也是最后一步,然后将那些在原链表上插入的新节点按顺序,尾插成一个新的链表;

    2.2.2代码实现:

    1. struct Node* BuyNode(int x)
    2. {
    3. struct Node* New = (struct Node*)malloc(sizeof(struct Node));
    4. New->val = x;
    5. New->next = NULL;
    6. New->random = NULL;
    7. return New;
    8. }
    9. struct Node* copyRandomList(struct Node* head)
    10. {
    11. struct Node* cur = head;
    12. //先复制单链表
    13. while(cur)
    14. {
    15. struct Node* cnext = cur->next;
    16. struct Node* New = BuyNode(cur->val);
    17. cur->next = New;
    18. New->next = cnext;
    19. cur = cur->next->next;
    20. }
    21. //给定random
    22. cur = head;
    23. while(cur)
    24. {
    25. if(cur->random)
    26. {
    27. cur->next->random = cur->random->next;
    28. }
    29. cur = cur->next->next;
    30. }
    31. //生成新链表
    32. cur = head;
    33. struct Node* Bhead = (struct Node*)malloc(sizeof(struct Node));
    34. Bhead->next = NULL;
    35. struct Node* tail = Bhead;
    36. int x = 1;
    37. while(cur)
    38. {
    39. if(x % 2 == 0)
    40. {
    41. tail->next = cur;
    42. tail = tail->next;
    43. }
    44. x++;
    45. cur = cur->next;
    46. }
    47. return Bhead->next;
    48. }

    以上就是本博客的所有内容了!

  • 相关阅读:
    Kubernetes控制平面组件:API Server
    面向对象07:简单小结类与对象
    【SSM框架】MyBatis的各种查询功能
    第九章 内置模块
    Android应用保活攻略
    linux系统安装步骤
    MyBatis流式查询
    存一个滤波器的截图。免的过段时间忘了
    以太网中的各种帧结构
    Java - List 去重,获取唯一值,分组列出所属对应集合
  • 原文地址:https://blog.csdn.net/weixin_61766635/article/details/127873082