每日一题(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;}测试用例如方法一,完。
- 每日一题(68) - 复杂链表的复制
- 复杂链表的复制【每日一题】
- 【每日一题-5】复杂链表的复制
- 算法题:复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- 复杂链表的复制
- jQuery一些方法总结
- 对一个结构体或类的数组进行排序
- 神器,神奇,jEdit
- 刚子扯谈:源于Chanel的图片描述
- C++面试题
- 每日一题(68) - 复杂链表的复制
- 公告
- flex布局
- NSNotificationCenter 的详细说明
- 算法导论笔记一:算法设计之分治法
- Unity3D 面试
- 黑马程序员—IO流(上)字符流、字节流
- 香港或国外服务器如何提高访问速度
- 基于Platinum库的DMS实现(android)