复杂链表的复制

简介: 题目描述:有一个复杂链表,其结点除了有一个Next指针指向下一个结点外,还有一个random指向链表中的任意结点或者NULL。其链表的定义如下:public class RandomListNode { int label; Rand...

题目描述:有一个复杂链表,其结点除了有一个Next指针指向下一个结点外,还有一个random指向链表中的任意结点或者NULL。其链表的定义如下:

public class RandomListNode {
    int label;
    RandomListNode next = null;
    RandomListNode random = null;

    RandomListNode(int label) {
        this.label = label;
    }
}

请实现 public RandomListNode Clone(RandomListNode pHead) 函数实现克隆一个链表。


解决思路:

  • 暴力的解法:首先只复制链表,不管random指针。然后再遍历原链表,复制random指针。复制random指针的方法是根据原链表从头开始,而指向复制链表的指针也同时开始,判断random指针是指向哪一个结点,然后根据位置对应,把复制链表的指针的位置赋值给random。好吧,其实画个图很简单。


    img_c80a1fbdfa5b9cbf96f0c760c5e09720.jpe
import java.util.*;

public class Main {

    class RandomListNode{
        public int label;
        public RandomListNode next = null;
        public RandomListNode random = null;

        public RandomListNode(int label){
            this.label = label;
        }
    }

    public RandomListNode Clone(RandomListNode pHead){
        if(pHead == null)
            return null;
        RandomListNode temp = pHead;
        RandomListNode head = new RandomListNode(temp.label);
        RandomListNode p = head;
        if(temp.next != null)
            temp = temp.next;
        //首先把只复制基本的链表

        while (temp != null){
            RandomListNode node = new RandomListNode(temp.label);
            p.next = node;
            node.next = null;
            p = p.next;
            temp = temp.next;
        }
        //然后复制random指针
        p = head;
        temp = pHead;
        while (p != null){
            if(temp.random == null){
                p.random = null;
                p = p.next;
                temp = temp.next;
                continue;
            }

            RandomListNode t = pHead;
            RandomListNode q = head;
            while(t != null){ //t和q只需要判断一个就行
                if(temp.random == t)
                    break;
                t = t.next;
                q = q.next;
            }

            p.random = q;
            p = p.next;
            temp = temp.next;
        }
        return head;
    }

    public static void main(String[] args) {
        RandomListNode node1 = new Main().new RandomListNode(1);
        RandomListNode node2 = new Main().new RandomListNode(2);
        RandomListNode node3 = new Main().new RandomListNode(3);
        RandomListNode node4 = new Main().new RandomListNode(4);
        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = null;
        node1.random = null;
        node3.random = node1;
        RandomListNode head = new Main().Clone(node1);
        System.out.println(head);
        System.out.println(head.random);
        head = head.next;
        System.out.println(head.random);
        head = head.next;
        System.out.println(head.random);
    }
}

  • 本题一种巧妙的解法是,将每个复制后的结点都跟在原结点后面,步骤如下:
    1.复制每个结点,如复制结点A得到A1,并将A1插到结点A后面。
    2.重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random.next
    3.拆分链表,将原链表拆分成原链表和复制后的链表
import java.util.*;

public class Main {

    class RandomListNode{
        public int label;
        public RandomListNode next = null;
        public RandomListNode random = null;

        public RandomListNode(int label){
            this.label = label;
        }
    }

    public RandomListNode Clone(RandomListNode pHead){
        if(pHead == null)
            return null;
        RandomListNode currentNode = pHead;
        //1.复制每个结点,如复制结点A得到A1,将A1插到A后面
        while (currentNode != null){
            RandomListNode copyNode = new RandomListNode(currentNode.label);
            RandomListNode p = currentNode.next;
            copyNode.next = p;
            currentNode.next = copyNode;
            currentNode = p;
        }

        //2.重新遍历链表,复制老结点的随机指针给新结点,如A1.random = A.random.next
        currentNode = pHead;
        while (currentNode != null){
            currentNode.next.random = (currentNode.random == null) ? null : currentNode.random.next;
            currentNode = currentNode.next.next;
        }

        //3.拆分链表,将原链表拆分成原链表和复制后的链表
        currentNode = pHead;
        RandomListNode copyHead = currentNode.next;
        while (currentNode != null){
            RandomListNode p = currentNode.next;
            currentNode.next = p.next;
            if(p.next != null)
                p.next = p.next.next;
            currentNode = currentNode.next;
        }
        return copyHead;
    }

    public static void main(String[] args) {
        RandomListNode node1 = new Main().new RandomListNode(1);
        RandomListNode node2 = new Main().new RandomListNode(2);
        RandomListNode node3 = new Main().new RandomListNode(3);
        RandomListNode node4 = new Main().new RandomListNode(4);
        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = null;
        node1.random = null;
        node3.random = node1;
        RandomListNode head = new Main().Clone(node1);
        System.out.println(head);
        System.out.println(head.random);
        head = head.next;
        System.out.println(head.random);
        head = head.next;
        System.out.println(head.random);
    }
}

目录
相关文章
|
程序员
【Leetcode】拿捏链表(五)——138. 复制带随机指针的链表
【Leetcode】拿捏链表(五)——138. 复制带随机指针的链表
58 0
【Leetcode】拿捏链表(五)——138. 复制带随机指针的链表
复制含有随机指针节点的链表
复制含有随机指针节点的链表
75 0
AC 剑指 Offer 35. 复杂链表的复制
AC 剑指 Offer 35. 复杂链表的复制
68 0
AC 剑指 Offer 35. 复杂链表的复制
|
存储 机器学习/深度学习
复制带随机指针的链表(中等难度)
复制带随机指针的链表(中等难度)
58 0
复制带随机指针的链表(中等难度)
|
Java Python
LeetCode 第 138 题:复制带随机指针的链表(Python 代码)
给定一个长度为 n 的链表,每个节点比普通的节点多了一个额外的随机指针 ramdom,该指针可以指向链表中的任何节点或空节点。构造这个链表的深拷贝。所谓的深拷贝,就是完全生成一个新的对象,内存地址都是不同的,这样改变拷贝之前变量,就不会影响到拷贝的变量。
94 0
|
存储 前端开发 程序员
复杂链表的复制
复杂链表的复制
91069 0
复杂链表的复制
|
C++ Python
字节跳动笔试题——复杂链表的复杂——剑指 Offer 35. 复杂链表的复制——python && C++源代码
字节跳动笔试题——复杂链表的复杂——剑指 Offer 35. 复杂链表的复制——python && C++源代码
字节跳动笔试题——复杂链表的复杂——剑指 Offer 35. 复杂链表的复制——python && C++源代码
|
算法 Java
Map与Set高频面试算法题(只出现一次的数字,复制带随机指针的链表,宝石与石头,旧键盘,前k个高频单词)(Java实现)
给一个非空整数数组,只有一个元素出现了一次,剩余的元素都出现了两次,,请找出那个只出现一次的数字
Map与Set高频面试算法题(只出现一次的数字,复制带随机指针的链表,宝石与石头,旧键盘,前k个高频单词)(Java实现)
(Java)链表OJ题---LeetCode 138 复制带随机指针的链表
给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点 。例如,如果原链表中有 X 和 Y 两个节点,其中 X.random --> Y 。那么在复制链表中对应的两个节点 x 和 y ,同样有 x.random --> y 。
(Java)链表OJ题---LeetCode 138 复制带随机指针的链表
|
算法
【刷算法】复杂链表的复制
【刷算法】复杂链表的复制