面试题30:复杂链表的复制

来源:互联网 发布:数据库攻击技术 编辑:程序博客网 时间:2024/05/15 08:52

题目:请实现函数ComplexListNode* Clone(ComplexListNode* pHead),复制一个复杂链表。在复制链表中,每一个结点除了有一个m_pNext指针指向下一个结点处,还有一个m_pSibling指向链表中的任意结点或者NULL。

结点定义如下:

struct ComplexListNode{int m_nValue;ComplexListNode* m_pNext;ComplexListNode* m_pSibling;};

思路:
首先要明白复制链表的意思,是重新new相同数量的结点,然后将这些结点按原来链表的的链接方式连起来。

如果没有那个任意指针,则可以按顺序复制链表就行了。

 当然可以先复制Next指针,时间复杂度O(n),再复制pSibling指针,由于要查找,重新定位,时间复杂度O(n^2)。

当然也可以先复制Next指针,然后将原结点指针和新节点指针用map对应起来,这样用O(n)的空间换来O(1)的查找时间,最后的总时间复杂度为O(n)。

下面提供一种O(n)时间复杂度,O(1)空间复杂度的思路(参考剑指offer):

第一步:将复制的结点接在原结点的后面。

第二步:复制pSibling。

第三步:将链表分成两个链表。

#include <iostream>    #include <vector> #include <queue>#include <string>    #include <stack>    #include <algorithm>    using namespace std;struct ComplexListNode{char m_nValue;ComplexListNode* m_pNext;ComplexListNode* m_pSibling;ComplexListNode(char val) :m_nValue(val), m_pNext(NULL), m_pSibling(NULL){}};/*将链表的每一个结点复制,且接在原来结点的后面*/void copyNode(ComplexListNode* head){while (head){ComplexListNode* cNode = new ComplexListNode(head->m_nValue+'A'-'a');cNode->m_pNext = head->m_pNext;head->m_pNext = cNode;head = cNode->m_pNext;}}/*复制pSibling,新结点的pSibling是前一个结点pSibling所指结点的下一个结点*/void copySibNode(ComplexListNode* head){while (head){ComplexListNode* hNextNode=head->m_pNext;hNextNode->m_pSibling = head->m_pSibling->m_pNext;  //keyhead = head->m_pNext->m_pNext;}}/*将链表分成两个链表,返回新链表的头结点*/ComplexListNode* dividList(ComplexListNode* head){if (!head) return NULL;ComplexListNode* newHead = head->m_pNext;while (head){ComplexListNode* temp= head->m_pNext;head->m_pNext = temp->m_pNext;head = head->m_pNext;if (head) temp->m_pNext = head->m_pNext;else temp->m_pNext = NULL;}return newHead;}ComplexListNode* Clone(ComplexListNode* pHead){copyNode(pHead);copySibNode(pHead);return dividList(pHead);}void display(ComplexListNode* a){while (a){cout << a->m_nValue << "--->"<<a->m_pSibling->m_nValue<<endl;a = a->m_pNext;}}int main(){ComplexListNode* a = new ComplexListNode('a');ComplexListNode* b = new ComplexListNode('b');ComplexListNode* c = new ComplexListNode('c');ComplexListNode* d = new ComplexListNode('d');a->m_pNext = b; b->m_pNext = c; c->m_pNext = d;a->m_pSibling = c; b->m_pSibling = d; c->m_pSibling = b; d->m_pSibling = a;ComplexListNode* newHead = Clone(a);display(newHead);return 0;}


下面补上利用hash table思想的代码:

#include <iostream>    #include <vector> #include <queue>#include <string>    #include <stack>    #include <algorithm> #include <map>using namespace std;struct ComplexListNode{char m_nValue;ComplexListNode* m_pNext;ComplexListNode* m_pSibling;ComplexListNode(char val) :m_nValue(val), m_pNext(NULL), m_pSibling(NULL){}};ComplexListNode* copyNode(ComplexListNode* pHead, map<ComplexListNode*, ComplexListNode*> &hash){if (!pHead) return NULL;ComplexListNode* newHead = NULL;ComplexListNode* pre = NULL;while (pHead){ComplexListNode* temp = new ComplexListNode(pHead->m_nValue + 'A' - 'a');if (!newHead) newHead = temp;else pre->m_pNext = temp;hash.insert(make_pair(pHead, temp));pHead = pHead->m_pNext;pre = temp;}return newHead;}void copySibNode(ComplexListNode* pHead, ComplexListNode* nHead, map<ComplexListNode*, ComplexListNode*> &hash){while (pHead){nHead->m_pSibling = hash[pHead->m_pSibling];pHead = pHead->m_pNext;nHead = nHead->m_pNext;}}ComplexListNode* Clone(ComplexListNode* pHead){map<ComplexListNode*, ComplexListNode*> hash;ComplexListNode* newHead = copyNode(pHead, hash);copySibNode(pHead, newHead, hash);return newHead;}void display(ComplexListNode* a){while (a){cout << a->m_nValue << "--->"<< a->m_pSibling->m_nValue << endl;a = a->m_pNext;}}int main(){ComplexListNode* a = new ComplexListNode('a');ComplexListNode* b = new ComplexListNode('b');ComplexListNode* c = new ComplexListNode('c');ComplexListNode* d = new ComplexListNode('d');a->m_pNext = b; b->m_pNext = c; c->m_pNext = d;a->m_pSibling = c; b->m_pSibling = d; c->m_pSibling = b; d->m_pSibling = a;ComplexListNode* newHead = Clone(a);display(newHead);return 0;}


0 0
原创粉丝点击