剑指offer之复杂链表的复制(C++/Java双重实现)

1.题目描述

请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
事例1:
在这里插入图片描述输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
事例2:
在这里插入图片描述
输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
事例3:
在这里插入图片描述输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]
事例4:
输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null。
注意:
-10000 <= Node.val <= 10000
Node.random 为空(null)或指向链表中的节点。
节点数目不超过 1000 。

在这里插入图片描述

2.题目分析

在这里插入图片描述

3.代码实现

3.1C++代码:
/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/
class Solution {
public:
    Node* copyRandomList(Node* head) {
        if(head==NULL)
            return NULL;
        Node* head1=head;
        //复制备份所有节点
        while(head1!=NULL)
        {
            Node* newnode=new Node(head1->val);
            newnode->next=head1->next;
            head1->next=newnode;
            head1=newnode->next;//移动节点指针
        }
        //更新每个备份节点的指针指向
        head1=head;
        while(head1!=NULL)
        {
            Node* randmnode=head1->random;
            if (head1->random!=NULL)//一定要判断是否为空,只有非空节点才能操作,切记
				head1->next->random = randmnode->next;
            head1=head1->next->next;//移动节点指针,一次性跳跃两个节点
        }
        //分离两个链表
        head1=head;
        Node* head2=new Node(-1);
        Node* curp=head2;
        while(head1!=NULL)
        {
            Node* nextnode=head1->next;
            curp->next=nextnode;
            head1->next=nextnode->next;//重新连接next指针
            head1=head1->next;//移动head1节点指针
            curp=nextnode;//移动curp节点指针
        }
        return head2->next;
    }
};

这里注意:原链表不能销毁

3.1Java代码:
/*
// 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 Node copyRandomList(Node head) {
           if(head==null)
            return null;
        Node head1=head;
        //复制备份所有节点
        while(head1!=null)
        {
            Node newnode=new Node(head1.val);
            newnode.next=head1.next;
            head1.next=newnode;
            head1=newnode.next;//移动节点指针
        }
        //更新每个备份节点的指针指向
        head1=head;
        while(head1!=null)
        {
            Node randmnode=head1.random;
            if (head1.random!=null)//一定要判断是否为空,只有非空节点才能操作,切记
				head1.next.random = randmnode.next;
            head1=head1.next.next;//移动节点指针,一次性跳跃两个节点
        }
        //分离两个链表
        head1=head;
        Node head2=new Node(-1);
        Node curp=head2;
        while(head1!=null)
        {
            Node nextnode=head1.next;
            curp.next=nextnode;
            head1.next=nextnode.next;//重新连接next指针
            head1=head1.next;//移动head1节点指针
            curp=nextnode;//移动curp节点指针
        }
        return head2.next;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_45737068/article/details/107101036
今日推荐