[剑指Offer]35-复杂链表的复制

链接

https://www.nowcoder.com/practice/f836b2c43afc4b35ad6adc41ec941dba?tpId=13&tqId=11178&tPage=2&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking

题意

输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。

解题思路

方法一:较优,时间复杂度O(N),空间复杂度O(N)

  • 第一遍,复制原始链表并暂不给复制节点的random指针赋值,同时把节点与copy及copy对应节点的地址<N,N'>信息存到哈希表。
  • 第二遍,给复制节点的random指针赋值时,有N'->random=map[S],而哈希查找时间复杂度O(1)

方法二:优,时间复杂度O(N),不需要额外辅助空间

  • 第一遍,把copy节点连到原链对应节点后面,暂不处理random指针。
  • 第二遍,给复制节点random指针赋值,N'->random=N->random->next;
  • 第三遍,把制造出的链表拆成愿链表和新copy链表

代码

使用方法二、特别注意注释的两个地方,即注意防止非法访问。

/*
struct RandomListNode {
    int label;
    struct RandomListNode *next, *random;
    RandomListNode(int x) :
            label(x), next(NULL), random(NULL) {
    }
};
*/
class Solution {
public:
    RandomListNode* Clone(RandomListNode* pHead)
    {
        if(!pHead){
            return nullptr;
        }
        pHead=addCopyNode(pHead);
        pHead=addRandomPtr(pHead);
        RandomListNode *pCopy=separateList(pHead);
        return pCopy;
    }
private:
    RandomListNode* addCopyNode(RandomListNode* pHead){
        RandomListNode *p=pHead;
        while(p){
            RandomListNode *pCopyNode=new RandomListNode(p->label);
            pCopyNode->next=p->next;
            p->next=pCopyNode;
            p=pCopyNode->next;
        }
        return pHead;
    }
    
    RandomListNode* addRandomPtr(RandomListNode* pHead){
        RandomListNode *p=pHead;
        while(p){
            if(p->random){//
                p->next->random=p->random->next;
            }
            p=p->next->next;
        }
        return pHead;
    }
    
    RandomListNode* separateList(RandomListNode* pHead){
        RandomListNode *p=pHead;
        RandomListNode *pCopyHead=pHead->next;
        
        while(p){
            //p指向原节点 ;当p非空 , p->next->next一定可以访问
            RandomListNode *tempPtr=p->next;
            p->next=tempPtr->next;
            
            //p指向copy节点 ;  要区分原节点再写一遍 ,因为若p为copy节点, 当p非空 ,p->next->next可能不可访问
            p=tempPtr;
            tempPtr=p->next;
            if(tempPtr){
                 p->next=tempPtr->next;
            }
            p=tempPtr;//保证这里的p指向下一个原节点
        }
        
        return pCopyHead;
    }

};

posted on 2019-03-19 12:12  coding_gaga  阅读(111)  评论(0编辑  收藏  举报

导航