剑指Offer - 九度1524 - 复杂链表的复制
2014-02-07 01:44
399 查看
剑指Offer - 九度1524 - 复杂链表的复制 2014-02-07 01:30
题目描述:
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。
输入:
输入可能包含多个测试样例,输入以EOF结束。
对于每个测试案例,输入的第一行为一个整数n (1<=n<=1000):n代表将要输入的链表元素的个数。(节点编号从1开始)。
接下来有n个数,表示链表节点中的值。
接下来有n个数Ti,Ti表示第i个节点的另一个指针指向。
Ti = 0 表示这个指针为NULL。
输出:
对应每个测试案例,
输出n行,每行有二个数,第一个代表当前节点值,第二个代表当前节点的特殊指针的值。
样例输入:
5 1 2 3 4 5 3 5 0 2 0
样例输出:
1 3 2 5 3 0 4 2 5 0
题意分析: 对于一个含有n个节点的单向链表,指针域中除了next之外,还有一个指向另一个节点或者指向NULL的随机指针。本题的任务是复制一份这样的链表出来。 我的思路,当然是先给节点编号,然后根据编号对应关系重建链表。 其中重要的一步,就是将这些链表节点和1~n的n个整数一一映射起来。这样一来,就能方便地表示随机指针中到底是谁指向谁了。 因为使用了map,所以映射的过程时间复杂度为O(n * log(n))。复制新链表时,也需要查反向映射,仍需要O(n * log(n))的时间。 如果使用适当的hash策略,可以做到接近O(1)的映射时间,时间复杂度也可以降到O(n),但需要额外编码就是了。空间复杂度为O(n)。 最后,不要偷懒直接用数组AC掉(^_^),AC的目的在于学会,而不是通过。
// 688806 zhuli19901106 1524 Accepted 点击此处查看所有case的执行结果 1160KB 3820B 50MS // 201402012144 #include <cstdio> #include <map> using namespace std; struct RandomListNode { int label; RandomListNode *next, *random; RandomListNode(int x) : label(x), next(NULL), random(NULL) {} }; // This code segment is copied from my leetcode problem set. class Solution { public: RandomListNode *copyRandomList(RandomListNode *head) { int n; if(NULL == head){ return NULL; } n = 0; RandomListNode *ptr; mri.clear(); mir.clear(); ptr = head; while(ptr != NULL){ ++n; mri[ptr] = n; ptr = ptr->next; } RandomListNode *root = new RandomListNode(0), *tail; ptr = head; int i = 0; tail = root; while(ptr != NULL){ ++i; tail->next = new RandomListNode(ptr->label); tail = tail->next; mir[i] = tail; ptr = ptr->next; } RandomListNode *p1, *p2; p1 = head; p2 = root->next; while(p1 != NULL){ if(p1->random != NULL){ p2->random = mir[mri[p1->random]]; } p1 = p1->next; p2 = p2->next; } head = root->next; delete root; mir.clear(); mri.clear(); return head; } RandomListNode *deleteList(RandomListNode *head) { RandomListNode *ptr1, *ptr2; if (NULL == head) { return NULL; } ptr1 = head; while (ptr1 != NULL) { ptr2 = ptr1->next; delete ptr1; ptr1 = ptr2; } return NULL; } private: map<RandomListNode *, int> mri; map<int, RandomListNode *> mir; }; int main() { map<RandomListNode *, int> mri; map<int, RandomListNode *> mir; int n, i; int label; RandomListNode *head1, *head2, *tail, *ptr; Solution solution; while (scanf("%d", &n) == 1) { mri.clear(); mir.clear(); head1 = head2 = tail = NULL; for (i = 1; i <= n; ++i) { scanf("%d", &label); if (tail == NULL) { head1 = tail = new RandomListNode(label); } else { tail->next = new RandomListNode(label); tail = tail->next; } mri[tail] = i; mir[i] = tail; } for (i = 1; i <= n; ++i) { scanf("%d", &label); if (label > 0) { ptr = mir[i]; ptr->random = mir[label]; } } head2 = solution.copyRandomList(head1); ptr = head2; while (ptr != NULL) { printf("%d ", ptr->label); if (ptr->random != NULL) { printf("%d\n", ptr->random->label); } else { printf("0\n"); } ptr = ptr->next; } head1 = solution.deleteList(head1); head2 = solution.deleteList(head2); } return 0; } /* // 688773 zhuli19901106 1524 Accepted 点击此处查看所有case的执行结果 1024KB 544B 40MS // 201402012022 #include <cstdio> #include <vector> using namespace std; int main() { vector<int> va, vb; int n, i; int a, b; while (scanf("%d", &n) == 1) { va.clear(); vb.clear(); va.push_back(0); vb.push_back(0); for (i = 1; i <= n; ++i) { scanf("%d", &a); va.push_back(a); } for (i = 1; i <= n; ++i) { scanf("%d", &b); vb.push_back(b); } for (i = 1; i <= n; ++i) { printf("%d %d\n", va[i], va[vb[i]]); } } return 0; } */
相关文章推荐
- 【剑指Offer面试题】 九度OJ1524:复杂链表的复制
- 【剑指Offer面试编程题】题目1524:复杂链表的复制--九度OJ
- 【剑指Offer面试编程题】题目1524:复杂链表的复制--九度OJ
- 【剑指Offer面试编程题】题目1524:复杂链表的复制--九度OJ
- 【剑指Offer面试编程题】题目1524:复杂链表的复制--九度OJ
- 【剑指Offer】复杂链表的复制
- [剑指Offer] 25.复杂链表的复制
- 剑指Offer 26 复杂链表的复制
- 剑指Offer---面试题26:复杂链表的复制
- 剑指offer——复杂链表的复制(还不错,空间优先法和时间优先法)
- 【剑指offer】复杂链表的复制
- 剑指offer-复杂链表的复制
- (C++)剑指offer-25:复杂链表的复制(分解让复杂问题简单)(再理解)
- 剑指offer题解 复杂链表的复制
- 剑指offer面试题[26]-复杂链表的复制
- 剑指offer--面试题26:复杂链表的复制--Java实现
- 剑指offer——复杂链表的复制
- 【面试题】剑指Offer-26-复杂链表的复制
- 剑指offer第二十五题【复杂链表的复制】c++实现
- 剑指Offer_25_复杂链表的复制