复制带随机指针的链表——LeetCode

Posted 勇敢牛牛不怕困难@帅

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了复制带随机指针的链表——LeetCode相关的知识,希望对你有一定的参考价值。

力扣第138题-复制带随机指针的链表

力扣题目描述

给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。
构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。
例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y
返回复制链表的头节点。
用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:
val:一个表示 Node.val 的整数。
random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 null 。
你的代码 只 接受原链表的头节点 head 作为传入参数。

示例分析

由示例可以看出链表除了多一个随机指向结点之外和普通的链表没有什么区别

读懂题意

这一道题目属于中等难度的题目,题目的含义还是比较容易理解!给定一个长度为n的链表,每个结点除了指向下一个结点的next结点之外,还包含一个额外的随机结点,且随机结点是随机指向结点。要求我们复制深拷贝出一个新链表和原来的链表一模一样,就连随机访问结点指向也是相同的。

解题思路

首先可以抛开随机访问结点,只考虑结点的复制,相对来讲就简单很多,将创建出来的结点用集合保存起来,最后在连接起来,构成一个链表。创建完成之后,再来考虑随机访问结点,如何来处理,此时结点在集合中是有一定顺序的,我们只需要知道 随机结点指向的下标是第几个就可以了,所以我们依次去遍历原链表的随机结点的指向,最后把每一个随机结点指向的下标用集合保存起来,最后将每个结点的随机结点指向指定的结点位置即可

实现代码

/*
// 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 ArrayList<Integer> arr = new ArrayList<>();
    public void getIndex(Node test,Node head,int size){
        Node p =head;
        for(int i=0;i<size;i++){
            if(test.random==p){
                arr.add(i);
                break;
            }
            p = p.next;
        }
    }
    public Node copyRandomList(Node head) {
        if(head==null) return null;
        ArrayList<Node> list = new ArrayList<>();//保存各个结点
        Node node = head;
        int index =0;
        while(node!=null){//所有结点加入list集合
            Node newN =new Node(node.val);
            list.add(newN);
            node=node.next;
        }
        Node k = null;//把最后一个空结点也加入其中
        list.add(k);
        //此时获取到了所有结点,此时并未连接
        int length = list.size();//链表长度n,包括null结点
        for(int i=0;i<length-1;i++){//各结点连接起来,构成新的链表
            list.get(i).next = list.get(i+1);
        }
        //此时构成链表,随机结点为null

        //创建一个方法去获取每个节点的随机访问结点指向的下标
        Node test = head;
        while(test!=null){
            getIndex(test,head,length);
            test=test.next;
        }
        //连接结点的随机访问结点
        Node q = list.get(0);
        for(int i=0;i<length-1;i++){
            q.random = list.get(arr.get(i));
            q = q.next;
        }

        return list.get(0);

    }
}

结果

以上是关于复制带随机指针的链表——LeetCode的主要内容,如果未能解决你的问题,请参考以下文章

复制带随机指针的链表——LeetCode

LeetCode-链表复制带随机指针的链表

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

LeetCode(算法)- 138. 复制带随机指针的链表

Leetcode No.138 复制带随机指针的链表(回溯)

Leetcode No.138 复制带随机指针的链表(回溯)