• Leetcode138_随机链表的复制


    1.leetcode原题链接:. - 力扣(LeetCode)

    2.题目描述

    给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。

    构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 

    例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。

    返回复制链表的头节点。

    用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:

    • val:一个表示 Node.val 的整数。
    • random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  null 。

    你的代码  接受原链表的头节点 head 作为传入参数。

    示例 1:

    输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
    输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
    

    示例 2:

    输入:head = [[1,1],[2,1]]
    输出:[[1,1],[2,1]]
    

    示例 3:

    输入:head = [[3,null],[3,0],[3,null]]
    输出:[[3,null],[3,0],[3,null]]
    

    提示:

    • 0 <= n <= 1000
    • -104 <= Node.val <= 104
    • Node.random 为 null 或指向链表中的节点。

    3.实现方法

    方法一:使用哈希表

    思路:定义一个Map,key是每个Node节点,value是对应Node创建与Node.val相等的新节点,直接从Map中获取新节点的的next和random。

    1. /*
    2. // Definition for a Node.
    3. class Node {
    4. int val;
    5. Node next;
    6. Node random;
    7. public Node(int val) {
    8. this.val = val;
    9. this.next = null;
    10. this.random = null;
    11. }
    12. }
    13. */
    14. class Solution {
    15. public Node copyRandomList(Node head) {
    16. if(head==null){
    17. return null;
    18. }
    19. Map map =new HashMap<>();
    20. Node cur=head;
    21. while(cur != null){
    22. map.put(cur,new Node(cur.val));
    23. cur=cur.next;
    24. }
    25. cur=head;
    26. while(cur != null){
    27. //map.get(cur) 新节点,设置其next和random
    28. map.get(cur).next = map.get(cur.next);
    29. map.get(cur).random=map.get(cur.random);
    30. cur =cur.next;
    31. }
    32. return map.get(head);
    33. }
    34. }

    方法二

    1.对应指针A->B->C来说,直接把拷贝节点放到原节点的下一个节点,如:A->NA->B->NB->C->NC;

    2.设置拷贝节点的random,即拷贝节点的random指向原节点的random的next,如 A.random=C,即NA.random=A.random.next=NC;

    3.将每个拷贝节点从原链表中拆分出来即可。

    1. /*
    2. // Definition for a Node.
    3. class Node {
    4. int val;
    5. Node next;
    6. Node random;
    7. public Node(int val) {
    8. this.val = val;
    9. this.next = null;
    10. this.random = null;
    11. }
    12. }
    13. */
    14. class Solution {
    15. public Node copyRandomList(Node head) {
    16. if(head==null){
    17. return null;
    18. }
    19. //1.对应指针A->B->C来说,直接把拷贝节点放到原节点的下一个节点,如:A->NA->B->NB->C->NC;
    20. Node cur=head;
    21. Node next=null;
    22. while(cur !=null){
    23. next=cur.next;
    24. cur.next=new Node(cur.val);
    25. cur.next.next=next;
    26. cur=next;
    27. }
    28. //2.设置拷贝节点的random,即拷贝节点的random指向原节点的random的next,如 A.random=C,即NA.random=A.random.next=NC;
    29. cur =head;
    30. Node newNode=null;
    31. while(cur !=null){
    32. next=cur.next.next;
    33. newNode=cur.next;
    34. newNode.random = cur.random != null ? cur.random.next : null;
    35. cur=next;
    36. }
    37. //3.将每个拷贝节点从原链表中拆分出来即可。
    38. Node ret=head.next;
    39. cur =head;
    40. while(cur != null){
    41. next=cur.next.next;
    42. newNode=cur.next;
    43. cur.next=next;
    44. newNode.next=next==null? null :next.next;
    45. cur=next;
    46. }
    47. return ret;
    48. }
    49. }

  • 相关阅读:
    【收藏】计算机专业必读的经典书籍,不看后悔系列
    Opengl绘制三角形
    vsftp3.0 匿名用户,本地用户,虚拟用户,主动模式以及被动模式,docker vsftpd,k8s vsftpd
    【无标题】发的东方人
    使用frp+nginx内网穿透并配置https
    【JavaScript】浅拷贝与深拷贝
    java+ssm+mysql小区疫情管理系统
    C语言笔记第15篇:文件操作
    事物/现象/事情/东西/情况/表象
    oracle自启动的p***并行进程过多导致的process进程超限问题
  • 原文地址:https://blog.csdn.net/qq_45800511/article/details/137893086