第35题:LeetCode138. Copy List with Random Pointer

题目 

给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。

要求返回这个链表的深度拷贝。 


考点

1.hash 空间换时间 On^2->On

2.双指针,野指针的鲁棒判断


思路

1.复制节点到原链表后面。

copy->link->next 。只复制节点的值和next,不复制随机指针。cloneNode->random=nullptr;


2.复制对应的随机指针。

重置双指针->如果原节点有随机指针就copy->next


3.分解两个链表。

重新赋值两个指针->ori先走->clone后走->next


代码

/*
 * @lc app=leetcode.cn id=138 lang=cpp
 *
 * [138] 复制带随机指针的链表
 *
 * https://leetcode-cn.com/problems/copy-list-with-random-pointer/description/
 *
 * algorithms
 * Medium (23.92%)
 * Total Accepted:    3.6K
 * Total Submissions: 15.1K
 * Testcase Example:  '{}'
 *
 * 给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
 * 
 * 要求返回这个链表的深度拷贝。 
 * 
 */
/**
 * Definition for singly-linked list with a random pointer.
 * struct RandomListNode {
 *     int label;
 *     RandomListNode *next, *random;
 *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 * };
 */
class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) {
        if(!head )
            return head; 

        //1.clone linked list
        RandomListNode *oriNode  =   head;             
        while(oriNode)
        {
            RandomListNode *cloneNode  =   new RandomListNode(0); 
            //copy
            cloneNode->label   =   oriNode->label;
            cloneNode->next    =   oriNode->next;
            cloneNode->random  =   nullptr; 
            //link
            oriNode->next =   cloneNode; 
            //next
            oriNode       =   cloneNode->next;
        } 
        
        //2.clone random pointer
        oriNode   =   head; 
        while(oriNode)
        {
            //cloneNode
            RandomListNode *cloneNode   =   oriNode->next;
            //copy randomNode
            if(oriNode->random)
            {
                RandomListNode *oriRandom   =   oriNode->random;  
                cloneNode->random           =   oriRandom->next;//是原随机指针的next,不是原随机指针!
            }            
            //next oriNode
            oriNode   =   cloneNode->next;
        }

        //3.depart         
        //return:cloneHead
        RandomListNode *cloneHead   =   head->next;
        RandomListNode *cloneNode   =   cloneHead;  
        //oriNode Traversing from head
        oriNode     =   head;   
        while(oriNode)
        {
            //oriNode first
            oriNode->next   =   cloneNode->next;
            oriNode         =   oriNode->next; 
            //cloneNode second
            if(!oriNode)
                break;
            cloneNode->next =   oriNode->next;
            cloneNode       =   cloneNode->next;  
        }        
        return cloneHead;
    }  
};

二刷


 * 给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
 * 
 * 要求返回这个链表的深度拷贝。 
 * 
 */
/**
 * Definition for singly-linked list with a random pointer.
 * struct RandomListNode {
 *     int label;
 *     RandomListNode *next, *random;
 *     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 * };
 */
class Solution {
public:
    RandomListNode *copyRandomList(RandomListNode *head) 
    {
        if(!head)
            return head;

        //clone
        RandomListNode* oriNode=head;
        while(oriNode)
        {
            //copy
            RandomListNode* cloneNode=new RandomListNode(0);
            cloneNode->label=oriNode->label;
            cloneNode->next=oriNode->next;
            cloneNode->random=nullptr;
            //link
            oriNode->next=cloneNode;
            //next
            oriNode=cloneNode->next;            
        }
           
        //copy random
        oriNode=head;
        while(oriNode)
        {
            RandomListNode* cloneNode=oriNode->next;
            //copy
            if(oriNode->random)
            {
                cloneNode->random=oriNode->random->next;
            }
            //next
            oriNode=cloneNode->next;
        }
        
        //depart
        oriNode=head;
        RandomListNode* cloneNode=head->next;
        RandomListNode* cloneHead=cloneNode;//return
        
        while(oriNode)
        {
            oriNode->next=cloneNode->next;
            oriNode=oriNode->next;
            
            if(!oriNode)
                break;
            cloneNode->next=oriNode->next;
            cloneNode=cloneNode->next;
        }
        
        return cloneHead;
    }  
};

 


问题

猜你喜欢

转载自blog.csdn.net/weixin_41042404/article/details/87308965