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

在这里插入图片描述

在这里插入图片描述

这道题确实有难度,我想了很久都没想到如何实现复制链表的随机指针random变量。看了评论区的拼接+拆分解法,做了一次复现。

一、拼接+拆分解法

解题思路:

  1. 对链表的节点进行复制
    在这里插入图片描述

  2. 建立随机链表关系

  3. 分离两个链表

/*
// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}
*/
class Solution {
    public Node copyRandomList(Node head) {
        if(head==null){
            return null;
        }
        Node p=head;
        
        //将链表中的节点复制一份,但Random的关系仍然没有发生改变
        while(p!=null){
            Node copyNode=new Node(p.val);
            copyNode.next=p.next;
            p.next=copyNode;
            p=p.next.next;
        }
        //复制随机链表关系
        p=head;
        while(p!=null){
            if(p.random!=null){
                p.next.random=p.random.next;
            }
            p=p.next.next;
        }
        //链表分离
        p=head;
        Node tempP=head.next;
        Node newHead=head.next;//返回值:新链表
        while(p!=null){
            p.next=tempP.next;
            p=p.next;
            if(tempP.next!=null){
                tempP.next=tempP.next.next;
                tempP=tempP.next;
            }
        }
        return newHead;
    }
}

二、常规哈希表解法

通过构建原有链表与新建链表之间的映射关系来完成随机链表的关系复制。

/*
// Definition for a Node.
class Node {
    int val;
    Node next;
    Node random;

    public Node(int val) {
        this.val = val;
        this.next = null;
        this.random = null;
    }
}
*/
class Solution {
    public Node copyRandomList(Node head) {
        if(head==null){
            return null;
        }
        Node p=head;
        Map<Node,Node> map=new HashMap<>();
        while(p!=null){
            map.put(p,new Node(p.val));
            p=p.next;
        }
        p=head;
        while(p!=null){
            map.get(p).next=map.get(p.next);
            map.get(p).random=map.get(p.random);
            p=p.next;
        }
        return map.get(head);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值