leetcode 138. Copy List with Random Pointer(深copy带有random指针的链表)只遍历一遍

该博客主要讨论如何实现一个深拷贝功能,针对含有额外random指针的单向链表。在拷贝过程中,需要处理好每个节点的值复制以及random指针的指向问题。通过建立源链表与拷贝链表的一一映射关系,逐步遍历并创建新节点,确保新链表的next和random指针都正确指向新链表中的节点,从而保持链表状态的一致性。
摘要由CSDN通过智能技术生成

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

Construct a deep copy of the list. The deep copy should consist of exactly n brand new nodes, where each new node has its value set to the value of its corresponding original node. Both the next and random pointer of the new nodes should point to new nodes in the copied list such that the pointers in the original list and copied list represent the same list state. None of the pointers in the new list should point to nodes in the original list.

For example, if there are two nodes X and Y in the original list, where X.random --> Y, then for the corresponding two nodes x and y in the copied list, x.random --> y.

Return the head of the copied linked list.

The linked list is represented in the input/output as a list of n nodes. Each node is represented as a pair of [val, random_index] where:

val: an integer representing Node.val
random_index: the index of the node (range from 0 to n-1) that the random pointer points to, or null if it does not point to any node.
Your code will only be given the head of the original linked list.

该题是深copy一个带有random指针的单向链表。

思路:
如果一个单向链表不带有random指针,正常就是不断创建新的node,一步一步到tail即可。

多一个random指针会有什么影响呢?比如刚创建到第2个node,random却指向第4个node,这时第4个node还没有创建出来;或者已经创建到了第6个node,而random却指向第1个,那怎么能确定第1个是已经存在的node还是需要重新创建呢。
你可能会说我用一个HashSet保存已经创建的节点,不就知道是不是已经存在了。但是创建新节点的时候我只知道节点的值,并不知道random指针指向的node,为什么呢,因为random指向的node可能还没有创建出来。后面一旦修改了random指针,node就不一样了还怎么去找是不是已经存在。

但是可以确定的是,已经给的head指向的链表是确定的,中间不会再变了,可以通过head链表的节点来找到深copy出来的新节点。那么这就需要建立一一映射,一个head节点(key)对应一个新copy出来的节点(value)。

可以按照没有random的步骤,head一步一步向右走,走一步创建一个新节点(深copy),修改它的next节点和random节点(存在就直接指,不存在创建新的)。

    public Node copyRandomList(Node head) {
        if(head == null) return head;
        
        HashMap<Node, Node> pair = new HashMap<>();
        Node newHead = new Node(head.val);
        pair.put(head, newHead);
        Node tmp = newHead;
        
        while(head != null) {
            if(head.next != null) {
                Node node = new Node(head.next.val);
                if(!pair.containsKey(head.next)) {               
                    pair.put(head.next, node);
                    tmp.next = node;         
                } else {
                    tmp.next = pair.get(head.next);
                }
                
            }
            
            if(head.random != null) {
                Node random = new Node(head.random.val);
                if(!pair.containsKey(head.random)){
                    pair.put(head.random, random);
                    tmp.random = random;
                } else {
                    tmp.random = pair.get(head.random);
                }
            }
            head = head.next;
            tmp = tmp.next;
        }
        return newHead;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值