138_复制带随机指针的链表

简介: 138_复制带随机指针的链表

138_复制带随机指针的链表

 

package 链表;
import java.util.HashMap;
import java.util.Map;
public class _138_复制带随机指针的链表 {
    class Node {
        int val;
        Node next;
        Node random;
        public Node(int val) {
            this.val = val;
            this.next = null;
            this.random = null;
        }
    }
    //方法一:使用递归+ hashMap (因为随机指针:一个节点可能被多个其他节点指向)
    /** hashMpa 避免重复创建 **/
    /**
     * ,当我们拷贝节点时,「当前节点的随机指针指向的节点」可能还没创建,因此我们需要变换思路。一个可行方案是,我们利用回溯的方式,让每个节点的拷贝操作相互独立。
     */
    Map<Node, Node> cachedNode = new HashMap<Node, Node>();
    public Node copyRandomList(Node head) {
        if (head == null) {
            return null;
        }
        if (!cachedNode.containsKey(head)) {
            Node headNew = new Node(head.val);
            cachedNode.put(head, headNew);
            headNew.next = copyRandomList(head.next);
            headNew.random = copyRandomList(head.random);
        }
        return cachedNode.get(head);
    }
    /**
     * 间隔插秧法啦(把秧苗插进来后,以前是走一步,现在多了一个结点要多走一步)
     * 第一步:插入苗
     * 第二步:先处理随机指针的复制(原本有随机、next的复制都需要处理?):优先处理随机(之所以要把苗插入,就是为了实现在同一流水线具有同一规则,如果先处理next 导致已经变成两条链表了,拿不到随机了)
     * @author Huangyujun
     *
     */
    class Solution2 {
        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;
            }
            //第二步:先处理随机指针的复制(利用的是原来的链表非常方便的找到随机,而插入的苗的随机就是在原来的基础+1 【node.random.next】)
            for (Node node = head; node != null; node = node.next.next) {
                Node nodeNew = node.next;
                nodeNew.random = (node.random != null) ? node.random.next : null;
            }
            //第三步:处理next 指针的复制
            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;
        }
    }
}



目录
相关文章
|
存储 C语言
用指针处理链表
用指针处理链表
190 3
链表指针的传参,传值和传地址
本文讨论了链表操作中指针传参的问题,特别是指针的传值与传地址的区别,并提供了修正代码,以确保链表插入操作能正确地修改指针指向的地址。
116 1
链表指针的传参,传值和传地址
【数据结构OJ题】复制带随机指针的链表
力扣题目——复制带随机指针的链表
155 1
【数据结构OJ题】复制带随机指针的链表
|
存储
一篇文章了解区分指针数组,数组指针,函数指针,链表。
一篇文章了解区分指针数组,数组指针,函数指针,链表。
269 0
|
C语言
无头链表二级指针方式实现(C语言描述)
本文介绍了如何在C语言中使用二级指针实现无头链表,并提供了创建节点、插入、删除、查找、销毁链表等操作的函数实现,以及一个示例程序来演示这些操作。
161 0
|
Python
【Leetcode刷题Python】138. 复制带随机指针的链表
LeetCode上题目“138. 复制带随机指针的链表”的Python解决方案,包括两种方法:一种是在每个节点后复制一个新节点然后再分离出来形成新链表;另一种是构建一个字典来跟踪原始节点与其副本之间的映射关系,从而处理新链表的构建。
136 1
|
存储 算法 数据处理
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
【经典LeetCode算法题目专栏分类】【第7期】快慢指针与链表
|
存储 C语言
链表—初始化指针变和创建新的节点------区别应用分析
链表—初始化指针变和创建新的节点------区别应用分析
138 0
|
存储 缓存 搜索推荐
指针链表
指针链表
163 0