您的位置:首页 > 职场人生

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

2015-12-25 15:44 639 查看
题目:请实现函数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;  //key
head = 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: