每日一题(68) - 复杂链表的复制

来源:互联网 发布:tweenmax.js 百叶窗 编辑:程序博客网 时间:2024/05/17 04:38

题目和思路来自剑指Offer

题目


举例


思路:难点是怎么确定兄弟指针的指向。

思路(1)使用Map确定兄弟指针的指向

如上例,输入数据为 A,B,C,D、E

建立的map:

A - A'

B - B'

...

E - E'

初始化兄弟结点的值:

以结点A为例,要寻找结点A'的兄弟结点D'

遍历已有链表的结点A时,找到其兄弟结点D,之后根据Map,获得D',这里D'就是新链表结点A'的兄弟结点

这里,空间复杂度为O(n),时间复杂度为O(n),假设map查找时间为O(1)。

代码

#include <iostream>#include <map>#include <assert.h>using namespace std;struct Node{int m_nValue;Node* m_pNext;Node* m_pSbling;};/*根据已知链表,创建新链表,此时兄弟指针赋空*/Node* CreatNewList(Node* pHead,map<Node*,Node*>& mapCloneNode){Node* pNewHead = NULL; Node* pLastNew = NULL;Node* pCur = pHead;while (pCur){//创建链表Node* pNewNode = new Node;pNewNode->m_nValue = pCur->m_nValue;pNewNode->m_pSbling = NULL;pNewNode->m_pNext = NULL;if (!pNewHead){pNewHead = pNewNode;}else{pLastNew->m_pNext = pNewNode;}pLastNew = pNewNode;//把链表插入mapmapCloneNode.insert(make_pair(pCur,pNewNode));pCur = pCur->m_pNext;}return pNewHead;}/*根据A,查找A'*/Node* FindNew(map<Node*,Node*>& mapCloneNode,Node* pNode){if (pNode == NULL){return NULL;}map<Node*,Node*>::iterator itCur = mapCloneNode.find(pNode);if (itCur != mapCloneNode.end()){return itCur->second;}else{return NULL;}}/*根据A,查找A的兄弟*/void FindSbling(map<Node*,Node*>& mapCloneNode,Node* pHead,Node* pNewHead){Node* pCur = pHead;Node* pCurSbling = NULL;Node* pCurNew = pNewHead;while(pCur){pCurNew->m_pSbling = FindNew(mapCloneNode,pCur->m_pSbling);pCur = pCur->m_pNext;pCurNew = pCurNew->m_pNext;}}/*主函数*/Node* Clone(Node* pHead){assert(pHead);map<Node*,Node*> mapCloneNode;Node* pNewHead = CreatNewList(pHead,mapCloneNode); //创建新链表,但兄弟指针赋空FindSbling(mapCloneNode,pHead,pNewHead);//获得兄弟指针return pNewHead;}void Print(Node* pHead){Node* pCur = pHead;while(pCur){cout<<pCur->m_nValue<<" ";if (pCur->m_pSbling){cout<<pCur->m_pSbling->m_nValue<<endl;}else{cout<<0<<endl;}pCur = pCur->m_pNext;}cout<<endl;}Node* CreatList(){int nLen = 0;int nSblingData = 0;cin >> nLen;//创建结点Node* pHead = NULL;Node* pNew = NULL;Node* pLast = NULL;for (int i = 0;i < nLen;i++){pNew = new Node;cin>>pNew->m_nValue;pNew->m_pNext = NULL;pNew->m_pSbling = NULL;if (pHead == NULL){pHead = pNew;}else{pLast->m_pNext = pNew;}pLast = pNew;}//创建兄弟Node* pCur = pHead;Node* pCurTmp = pHead;while(pCur){cin>>nSblingData;//接受兄弟的下标pCurTmp = pHead;if (nSblingData == 0){pCur->m_pSbling = NULL;}else{while(pCurTmp && nSblingData != pCurTmp->m_nValue){pCurTmp = pCurTmp->m_pNext;}assert(pCurTmp);pCur->m_pSbling = pCurTmp;}pCur = pCur->m_pNext;}return pHead;}int main(){Node* pHead = NULL;Node* pNewHead = NULL;pHead = CreatList();Print(pHead);pNewHead = Clone(pHead);Print(pHead);system("pause");return 1;}
这里借用王道论坛的测试用例:题目1524:复杂链表的复制

附加带环的测试用例

输入:

5

1 2 3 4 5

3 2 1 5 4

输出:

1 3

2 2

3 1

4 5

5 4

思路(2)在旧链表中创建新链表,之后再从旧链表中拆分得到新链表

具体分为三步:

(1)在旧链表中创建新链表,此时不处理新链表的兄弟结点


(2)根据旧链表的兄弟结点,初始化新链表的兄弟结点


(3)从旧链表中拆分得到新链表


代码:

#include <iostream>#include <map>#include <assert.h>using namespace std;struct Node{int m_nValue;Node* m_pNext;Node* m_pSbling;};/*根据已知链表,创建新链表,此时兄弟指针赋空*/void CreatNewList(Node* pHead){assert(pHead);Node* pCur = pHead;while (pCur){//创建链表Node* pNewNode = new Node;pNewNode->m_nValue = pCur->m_nValue;pNewNode->m_pSbling = NULL;pNewNode->m_pNext = pCur->m_pNext;pCur->m_pNext = pNewNode;pCur = pCur->m_pNext->m_pNext;}}/*根据A,查找A的兄弟*/void InitSbling(Node* pHead){assert(pHead);Node* pCur = pHead;Node* pCurNext = NULL;while(pCur){pCurNext = pCur->m_pNext;if (pCur->m_pSbling){pCurNext->m_pSbling = pCur->m_pSbling->m_pNext;}pCur = pCur->m_pNext->m_pNext;}}Node* SeparateList(Node* pHead){assert(pHead);Node* pNewHead = NULL;Node* pCur = pHead;Node* pLastNew = NULL;while(pCur){if (pNewHead == NULL){pNewHead = pCur->m_pNext;}else{pLastNew->m_pNext = pCur->m_pNext;}pLastNew = pCur->m_pNext;pCur->m_pNext = pCur->m_pNext->m_pNext;pCur = pCur->m_pNext;}return pNewHead;}/*主函数*/Node* Clone(Node* pHead){assert(pHead);CreatNewList(pHead); //创建新链表,但兄弟指针赋空InitSbling(pHead);return SeparateList(pHead);}void Print(Node* pHead){Node* pCur = pHead;while(pCur){cout<<pCur->m_nValue<<" ";if (pCur->m_pSbling){cout<<pCur->m_pSbling->m_nValue<<endl;}else{cout<<0<<endl;}pCur = pCur->m_pNext;}cout<<endl;}Node* CreatList(){int nLen = 0;int nSblingData = 0;cin >> nLen;//创建结点Node* pHead = NULL;Node* pNew = NULL;Node* pLast = NULL;for (int i = 0;i < nLen;i++){pNew = new Node;cin>>pNew->m_nValue;pNew->m_pNext = NULL;pNew->m_pSbling = NULL;if (pHead == NULL){pHead = pNew;}else{pLast->m_pNext = pNew;}pLast = pNew;}//创建兄弟Node* pCur = pHead;Node* pCurTmp = pHead;while(pCur){cin>>nSblingData;//接受兄弟的下标pCurTmp = pHead;if (nSblingData == 0){pCur->m_pSbling = NULL;}else{while(pCurTmp && nSblingData != pCurTmp->m_nValue){pCurTmp = pCurTmp->m_pNext;}assert(pCurTmp);pCur->m_pSbling = pCurTmp;}pCur = pCur->m_pNext;}return pHead;}int main(){Node* pHead = NULL;Node* pNewHead = NULL;pHead = CreatList();Print(pHead);pNewHead = Clone(pHead);Print(pHead);system("pause");return 1;}
测试用例如方法一,完。

原创粉丝点击