复制带随机指针的链表_Java语言编写

复制带随机指针的链表

给定一个链表,每个结点包含一个额外增加的随机指针,该指针可以指向链表中的任何结点或空结点。要求返回这个链表的深拷贝。

示例:
在这里插入图片描述

输入:
{"$id":"1","next":{"$id":"2","next":null,"random":
{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}
解释:
结点 1 的值是 1,它的下一个指针和随机指针都指向结点 2.
结点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己.

提示:
必须返回给定头的拷贝作为对克隆列表的作用。
分成两步:
1.先复制所有的结点
2.处理 random 指向

简单复制无法解决(因为是浅拷贝)
需要先复制结点,后解决 random 问题
如果能从老的结点找到新的结点,问题好解决

结构:
1.---2.处理 random
3.拆开

在这里插入图片描述

步骤:

1.把原链表变成当前形式
利用 p1 遍历原链表的每个结点
创建新结点 p2
把 p2 插入到 p1 的后边

在这里插入图片描述

        Node p1=head;
        while(p1!=null){
            Node p2=new Node();
            p2.val=p1.val;
            p2.random=null;
            
            p2.next=p1.next;
            p1.next=p2;
            
            p1=p2.next;

2.处理 random 指向

在这里插入图片描述

        p1=head;
        while(p1!=null){
            Node p2=p1.next;
            if(p1.random!=null){
                p2.random=p1.random.next;
            }
            
            p1=p2.next;
        }

3.拆开
在这里插入图片描述

        p1=head;
        while(p1!=null){
            Node p2=p1.next;
            
            p1.next=p2.next;
            if(p2.next!=null){
                p2.next=p2.next.next;
            }
            
            p1=p1.next;
        }

Map

private static class NodeComparator implements Comparator<Node> {
    @Override
    public int compare(Node o1, Node o2) {
        return o1.val - o2.val;
    }
}

public static Node copyRandomList2(Node head) {
    Map<Node, Node> map = new TreeMap<>(new NodeComparator());
    Node newHead = null;
    Node newLast = null;
    Node cur = head;
    while (cur != null) {
        Node node = new Node();
        node.val = cur.val;
        if (newHead == null) {
            newHead = node;
        } else {
            newLast.next = node;
        }
        newLast = node;
        map.put(cur, node);
        cur = cur.next;
    }

    cur = head;
    Node node = newHead;
    while (node != null) {
        if (cur.random != null) {
            node.random = map.get(cur.random);
        } else {
            node.random = null;
        }

        cur = cur.next;
        node = node.next;
    }

    return newHead;
}
public class Solution {
    public CNode complexCopy(CNode head) {
        if (head == null) {
            return null;
        }
        CNode p1 = head;
        while (p1 != null) {
            CNode p2 = new CNode(p1.val);
            p2.next = p1.next;
            p1.next = p2;

            p1 = p2.next;
        }

        p1 = head;
        while (p1 != null) {
            CNode p2 = p1.next;
            if (p1.random != null) {
                p2.random = p1.random.next;
            }

            p1 = p2.next;
        }

        p1 = head;
        CNode newHead = head.next;

        while (p1 != null) {
            CNode p2 = p1.next;

            p1.next = p2.next;
            if (p2.next != null) {
                p2.next = p2.next.next;
            }

            p1 = p1.next;
        }

        return newHead;
    }
    
    /**
     * 1. 构建几组测试数据
     * 2. 进行测试
     * 3. 对测试结果进行打印
     * @return
     */
    private static void testComplexListCopy(Solution solution) {
        // 1. 构建测试数据
        CNode head = createComplexList1();
        // 2. 进行测试
        CNode resultHead = solution.copy(head);
        // 3. 对测试结果进行打印
        printCList(resultHead);
    }

    // CNode 必须实现一个 String toString() 方法
    private static void printCList(CNode head) {
        for (CNode cur = head; cur != null; cur = cur.next) {
            System.out.print(cur + " --> ");
        }
        System.out.println();
    }
    
    // CNode 必须有一个构造方法,形参是 int val
    // 并且,初始化后,next 和 random 都是 null
    private static CNode createComplexList1() {
        CNode n1 = new CNode(1);
        CNode n2 = new CNode(2);
        CNode n3 = new CNode(3);
        CNode n4 = new CNode(4);

        n1.random = n3; n2.random = n1; n3.random = n3;
        n1.next = n2; n2.next = n3; n3.next = n4;

        return n1;
    }
    
     /**
     * 测试面试题:
     * 1)复杂链表复制
     * @param args
     */
    public static void main(String[] args) {
        Solution solution = new Solution();
        testComplexListCopy(solution);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值