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

一.题目

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

二.输入输出示例 

输入:
{"$id":"1","next":{"$id":"2","next":null,"random":{"$ref":"2"},"val":2},"random":{"$ref":"2"},"val":1}

解释:
节点 1 的值是 1,它的下一个指针和随机指针都指向节点 2 。
节点 2 的值是 2,它的下一个指针指向 null,随机指针指向它自己。

三.解题方法

1.先忽略链表的random,生成与原链表val相同的结点,进行以下方式的插入;

原链表:1 -> 2 -> 3 -> 4 -> 5

插入后的链表:1 -> 1 -> 2 -> 2 -> 3 -> 3 -> 4 -> 4 ->5 -> 5 (其中加粗的为新节点,random为null)

2.通过观察可以发现新结点的random为原结点random的后继结点(next);

例如: 1.random = 3 那么 1.random = 1.random.next 即为3(注意区分加粗与不加粗)

通过此方法遍历‘插入后的链表’,即可将random拷贝至新结点;

3.将原链表与新节点形成的链表分离开来;

插入后的链表:1 -> 1 -> 2 -> 2 -> 3 -> 3 -> 4 -> 4 ->5 -> 5 

原链表:1 -> 2 -> 3 -> 4 -> 5

Copy链表:1 -> 2 -> 3 -> 4 -> 5

注意:在拆分时应给新链表赋一个head,否则将无法找到新链表的头结点

四.代码(Java实现)

/*
// Definition for a Node.
class Node {
    public int val;
    public Node next;
    public Node random;

    public Node() {}

    public Node(int _val,Node _next,Node _random) {
        val = _val;
        next = _next;
        random = _random;
    }
};
*/
class Solution {
    public Node copyRandomList(Node head) {
        if(head == null){        //如果时空链表则返回空
            return null;
        }
        Node cur = head;
        while(cur != null){          //形成新的链表
            Node new_Node = new Node(cur.val);
            new_Node.random = null;
            new_Node.next = cur.next;
            cur.next = new_Node;
            cur = new_Node.next;
        }   
        Node p1 = head;
        while(p1!=null){        //给新结点复制random
            Node p2 = p1.next;
            if(p1.random !=null){
                p2.random = p1.random.next;
            }
            p1 = p1.next.next;
        }
        Node new_list = head.next;
        p1 = head;
        while(p1!=null){        //将新链表与原链表拆分
            Node p2 = p1.next;
            p1.next = p2.next;
            p1 = p2.next;
            if(p2.next!=null){
                p2.next = p2.next.next;
                p2 = p1.next;
            }
        }
        return new_list;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值