复杂链表的复制

Posted tianzeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了复杂链表的复制相关的知识,希望对你有一定的参考价值。

题目

  请实现函数ComplexListNode* Clone(ComplexListNode* pHead),复制一个复杂链表,在复杂链表中,每个结点除了有一个pNext指针指向下一个结点之外,还有一个pSibling指向链表中的任意结点或者NULL。

思路

方法一

  复制原始链表上的每一个结点,并通过pNext连接起来;然后再设置每个结点的pSibling指针。

假设原始链表中某个结点N的pSibling指针指向结点S,那么就需要从头到尾遍历查找结点S,如果从原始链表的头指针开始,经过m步之后达到结点S,那么在复制链表中的结点N‘的pSibling指针指向的结点也是距离复制链表s步的结点。通过这种办法就可以为复制链表上的每个结点设置pSibling指针。

时间复杂度:O(N^2)

方法二

  方法1是通过链表查找来得到pSibling指针所指向的结点,实际上我们可以通过空间换取时间,将原始链表和复制链表的结点通过哈希表对应起来,这样查找的时间就从O(N)变为O(1)。具体如下:

复制原始链表上的每个结点N创建N‘,然后把这些创建出来的结点用pNext连接起来。同时把<N,N‘>的配对信息方法一个哈希表中;然后设置复制链表中的每个结点的pSibling指针,如果原始链表中结点N的pSibling指向结点S,那么在复制链表中,对应的N‘应该指向S‘。

时间复杂度:O(N)

方法三

  在不使用辅助空间的情况下实现O(N)的时间效率。

  1. 根据原始链表的每个结点N创建对应的N‘,然后将N‘通过pNext接到N的后面;
  2. 设置复制出来的结点的pSibling。假设原始链表上的N的pSibling指向结点S,那么其对应复制出来的N‘是N->pNext指向的结点,同样S‘也是结点S->pNext指向的结点。
  3. 把长链表拆分成两个链表,把奇数位置的结点用pNext连接起来的就是原始链表,把偶数位置的结点通过pNext连接起来的就是复制链表。

hash方法

struct ComplexListNode{
    int val;
    ComplexListNode* pNext;
    ComplexListNode* pSibling;
    ComplexListNode():val(0),pNext(NULL),pSibling(NULL){};
};
 
typedef std::map<ComplexListNode*,ComplexListNode*> MAP;
 
ComplexListNode* CloneNodes(ComplexListNode* pHead,MAP &hashNode){
    ComplexListNode* pNode=new ComplexListNode();
    ComplexListNode* p=pNode;
    ComplexListNode* tmp;
 
    while(pHead!=NULL){
        tmp=new ComplexListNode();
        tmp->val=pHead->val;
        p->pNext=tmp;
        hashNode[pHead]=tmp;
        pHead=pHead->pNext;
        p=p->pNext;
    }
    return pNode->pNext;
}
 
void SetSiblings(ComplexListNode* pHead,ComplexListNode* pCopy,MAP &hashNode){
    while(pCopy!=NULL){
        pCopy->pSibling=hashNode[pHead->pSibling];
        pCopy=pCopy->pNext;
        pHead=pHead->pNext;
    }
}
 
ComplexListNode* ComplexListCopy(ComplexListNode* pHead){
    ComplexListNode* pCopy;
    MAP hashNode;
    pCopy=CloneNodes(pHead,hashNode);
    SetSiblings(pHead,pCopy,hashNode);
    return pCopy;
}

复制连接的方法

#include <iostream>
using namespace std;

struct node
{
    int data;
    struct node *next,*sibling;
};
class Solution
{
    public:
        Solution();
        void create();
        void print();
        
        node *clone(node *head);
        void clone_node(node *head);
        void con_sib_node(node *head);
        node *recon_node(node *head);
        node *head;
};
Solution::Solution()
{
    head=new node();
    head->next=nullptr;
    head->sibling=nullptr;
    head->data=0;
}
void Solution::create()
{
    if(head==nullptr)
        return;
    auto t=head;
    int x;
    while(1)
    {
        cin>>x;
        if(x)
        {
            t->next=new node();
            t=t->next;
            t->sibling=nullptr;
            t->data=x;
            t->next=nullptr;
        }
        else
        {
            t->next=nullptr;
            t->sibling=nullptr;
            break;
        }
    }
} 
void Solution::print()
{
    auto n=head->next;
    while(n)
    {
        cout<<n->data<<endl;
        n=n->next;
    }
}
node *Solution::clone(node *head)
{
    clone_node(head);
    con_sib_node(head);
    return recon_node(head);
}
void Solution::clone_node(node *head)
{
    node *n=head->next;
    while(n)
    {
        node *clone=new node();
        clone->data=n->data;
        clone->next=n->next;
        clone->sibling=nullptr;
        
        n->next=clone;
        n=clone->next;
    }
}
void Solution::con_sib_node(node *head)
{
    node *n=head->next;
    while(n)
    {
        node *clone=n->next;
        if(n->sibling)
            clone->sibling=n->sibling->next;
        n=clone->next;
    }
}
node *Solution::recon_node(node *head)
{
    node *n=head->next;
    node *h_clone=nullptr;
    node *n_clone=nullptr;
    
    if(n)
    {
        h_clone=n_clone=n->next;
        n->next=n_clone->next;
        n=n->next;
    }
    while(n)
    {
        n_clone->next=n->next;
        n_clone=n_clone->next;
        
        n->next=n_clone->next;
        n=n->next;
    }
    return h_clone;
}
int main() 
{
    Solution s;
    s.create();
     
    node *h=s.clone(s.head);
    return 0;
}

 

以上是关于复杂链表的复制的主要内容,如果未能解决你的问题,请参考以下文章

复杂链表的复制

剑指offer 25.复杂链表的复制

数据结构复杂链表的复制

复杂链表的复制

python解决复杂链表的复制

复杂链表的复制