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

在这里插入图片描述
在这里插入图片描述

简化写法:

class Solution {
    public Node copyRandomList(Node head) {
        if(head == null) return null;
        Node cur = head;
        Map<Node, Node> map = new HashMap<>();
        // 3. 复制各节点,并建立 “原节点 -> 新节点” 的 Map 映射
        while(cur != null) {
            map.put(cur, new Node(cur.val));
            cur = cur.next;
        }
        cur = head;
        // 4. 构建新链表的 next 和 random 指向
        while(cur != null) {
            map.get(cur).next = map.get(cur.next);
            map.get(cur).random = map.get(cur.random);
            cur = cur.next;
        }
        // 5. 返回新链表的头节点
        return map.get(head);
    }
}


复杂写法:

// 登录 AlgoMooc 官网获取更多算法图解
// https://www.algomooc.com
// 作者:程序员吴师兄
class Solution {
    public Node copyRandomList(Node head) {
        // 边界判断,一般链表的题目都需要判断头节点是否为空
        if(head == null ) return null;
        // 从链表的头节点开始遍历
        Node cur = head;
        // 使用一一对应的哈希表结构 Map 存放已经创建的节点
       Map<Node,Node> map = new HashMap<>();

        // 遍历原链表
        while( cur != null ) {
            // 以原链表的节点为 Key,构建一个 Map
            // Map 的 Value 为一个新链表中的节点
            // 新节点的值 val 和原链表的值 val 一样
            // 但原链表中的每个节点都有 next 和 random 指针,而 Map 中的 Value 没有 next 和 random 指针
            // map.put(Key,Value)
            Node newNode = new Node(cur.val);

            map.put(cur,newNode);

            // 查看下一个节点的情况
            cur = cur.next;
        }

        // 再次从链表的头节点开始遍历
        cur = head;

        // 遍历原链表
        while( cur != null ) {

            // 原链表节点 ----  新链表节点
            // key      ----- value
            // cur      ----- map.get(cur)

            // 0、在字典中找到一个 cur 为 key 对应的那个 value 值
            Node valueCur = map.get(cur);
            // 接下来,需要去寻找 valueCur 的 next 节点和 random 节点

            // 寻找 valueCur 的 next 节点
            // 1、获取当前节点 cur 在原链表中的 next 指针指向的节点
            Node keyNextNode  = cur.next;
            // 2、在字典中找到以 keyNextNode 为 key 对应的那个 value 值
            Node valueNextNode =  map.get(keyNextNode);
            // 3、那么新链表中的这个节点的 next 指针就是 valueNextNode
            valueCur.next = valueNextNode;

            // 寻找 valueCur 的 random 节点
            // 1、获取当前节点 cur 在原链表中的 random 指针指向的节点
             Node keyRandomNode =  cur.random;
            // 2、在字典中找到以 valueRandomNode 为 key 对应的那个 value 值
             Node valueRandomNode =  map.get(keyRandomNode);
            // 4、那么新链表中的这个节点的 next 指针就是 valueNextNode
            valueCur.random = valueRandomNode;

            //遍历下去,查看下一个节点
            cur = cur.next;

        }
        // 原链表节点 ----  新链表节点
        // key      ----- value
        // cur      ----- map.get(cur)
        // head     ----- map.get(head)
        return map.get(head);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值