zoukankan      html  css  js  c++  java
  • 复杂链表的复制

    题目

      请实现函数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;
    }
  • 相关阅读:
    sql server获取指定库下的所有表名
    sql根据字符将一行拆成多行
    刷题416. Partition Equal Subset Sum
    刷题394. Decode String
    刷题347. Top K Frequent Elements
    刷题309. Best Time to Buy and Sell Stock with Cooldown
    刷题338. Counting Bits
    刷题337. House Robber III
    刷题312. Burst Balloons
    刷题621. Task Scheduler
  • 原文地址:https://www.cnblogs.com/tianzeng/p/10204909.html
Copyright © 2011-2022 走看看