剑指 Offer 35. 复杂链表的复制

剑指 Offer 35. 复杂链表的复制(❤❤)

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。

在这里插入图片描述

解法一

回溯法+哈希表:

思路就是,random既然不好拷贝,那我就先把next解决了,再考虑random设置,next怎么解决,遍历原链表,遍历一个创建一个新节点,新节点全部放到hashmap中去,一直到最后一个的时候,所有节点都存在与hashmap中,这时候从最后一个设置random节点,判断对应原链表中的random在hashmap中有没有(这个时候已经是有了的),就直接从map中拿到这个节点设置为上一个节点的random。

class Solution {
    Map<Node,Node> map = new HashMap();
    public Node copyRandomList(Node head) {
        
        if(head == null){
            return head;
        }
        if(!map.containsKey(head)){
            Node NodeNew = new Node(head.val);
            map.put(head,NodeNew);
            NodeNew.next = copyRandomList(head.next);
            NodeNew.random = copyRandomList(head.random);
        }
        return map.get(head);

    }
}
解法二

链表复制+拆分

思路就是,既然你要复制一个链表,那我就把每个节点复制一遍接在对应的节点后面,再把复制节点的random指针都指向原节点的指针,再把这个链表一拆就行了。

步骤:

  • 添加节点,构造一个复制后的链表,比如A->B->C 复制之后就是A->A’->B->B’->C->C’
  • 将A ’ B’ C’ 的random指针分别指向对应ABC节点的random指针指向的节点下一个(即复制过后的random,比如A的random指向C,那么这里复制过后的A’的random指向C->next,也就是C‘)
  • 拆分链表,通过调整next指向将ABC A’B’C’拆分成两个链表,返回A’即可。
class Solution {
    public Node copyRandomList(Node head) {
        if (head == null) {
            return null;
        }
        //步骤一
        for (Node node = head; node != null; node = node.next.next) {
            Node nodeNew = new Node(node.val);
            nodeNew.next = node.next;
            node.next = nodeNew;
        }
        //步骤二
        for (Node node = head; node != null; node = node.next.next) {
            Node nodeNew = node.next;
            nodeNew.random = (node.random != null) ? node.random.next : null;
        }
        //步骤三
        Node headNew = head.next;
        for (Node node = head; node != null; node = node.next) {
            Node nodeNew = node.next;
            node.next = node.next.next;
            nodeNew.next = (nodeNew.next != null) ? nodeNew.next.next : null;
        }
        return headNew;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值