Copy List with Random Pointer(复制有随机指针的链表)

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.
题目意思是让我们复制一个链表,这个链表的特别之处在于除了有next指针外,还有一个random指针,具体见RandomListNode的定义代码:

/**
 * Definition for singly-linked list with a random pointer.
 * class RandomListNode {
 *     int label;
 *     RandomListNode next, random;
 *     RandomListNode(int x) { this.label = x; }
 * };
 */

那么此题的最直接的解题思路就是先不管random指针,复制一个一般的链表,这个只需要我们遍历一遍原链表,复制一波即可。考虑到还有个random指针,所以采用HashMap来储存原链表节点和新的复制的节点。在第二次遍历hashmap的时候再将random指针的信息复制给新链表,最后返回新链表的头节点即可。在实际代码中,链表类题目一般我会new一个dummy节点,让dummy.next指向头节点,这样做的好处是不用考虑原链表是否为null。具体代码如下:

public class Solution {
    /**
     * @param head: The head of linked list with a random pointer.
     * @return: A new head of a deep copy of the list.
     */
    public RandomListNode copyRandomList(RandomListNode head) {
        // write your code here

        Map<RandomListNode, RandomListNode> map = new HashMap<>();
        RandomListNode dummy = new RandomListNode(0);
        RandomListNode node = dummy;
        RandomListNode headCopy = head;

       while(head != null){
           RandomListNode newNode = new RandomListNode(head.label);
           map.put(head, newNode);
           node.next = newNode;
           node = node.next;
           head = head.next;
       }

       node = dummy.next;

       while(node != null){
           if(headCopy != null){
               node.random = map.get(headCopy.random);
           }
           headCopy = headCopy.next;
           node = node.next; 
       }

       return dummy.next;
    }
}

假设原链表1->2->3, 1的random指向3,2,3的random为null。
注意点:刚开始new了一个dummy node,然后将dummy node的内存地址赋值给声明的node节点,将原链表的head节点的内存地址赋值给声明的headCopy节点。之后第一个while循环就是要复制除了random指针的其余信息,包含label,next。首先判断原链表的head节点是否为空,不为空创建一个newNode,将head的值给它,然后将head和newNode对象都放入map中。注意此时head对象的label,next,random都不为空,而newNode对象的next和random一定是null。然后将newNode的内存地址赋值给node.next,则此时dummy node的next也被修改,因为dummy node和node目前是指向同一个内存地址。这样dummy node也就记录了原链表的第一个值,即dummy.next.label和dummy.next有值。然后就可以将node.next的内存地址赋值给node,这样就修改了node所记录的内存地址,从而继续遍历时dummy node不受影响。随后的循环每次将新的内存地址赋值给node.next,再修改node指向的内存地址。图示如下:
第一个while循环示意图
之后做的事情就比较简单了,取出原链表中的random信息赋值给新链表即可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值