剑指Offer

剑指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的目的在于学会,而不是通过。
  1 // 688806    zhuli19901106    1524    Accepted    点击此处查看所有case的执行结果    1160KB    3820B    50MS
  2 // 201402012144
  3 #include <cstdio>
  4 #include <map>
  5 using namespace std;
  6 
  7 struct RandomListNode {
  8     int label;
  9     RandomListNode *next, *random;
 10     RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
 11 };
 12 
 13 // This code segment is copied from my leetcode problem set.
 14 class Solution {
 15 public:
 16     RandomListNode *copyRandomList(RandomListNode *head) {
 17         int n;
 18         
 19         if(NULL == head){
 20             return NULL;
 21         }
 22         
 23         n = 0;
 24         RandomListNode *ptr;
 25         
 26         mri.clear();
 27         mir.clear();
 28         
 29         ptr = head;
 30         while(ptr != NULL){
 31             ++n;
 32             mri[ptr] = n;
 33             ptr = ptr->next;
 34         }
 35         
 36         RandomListNode *root = new RandomListNode(0), *tail;
 37         ptr = head;
 38         int i = 0;
 39         tail = root;
 40         while(ptr != NULL){
 41             ++i;
 42             tail->next = new RandomListNode(ptr->label);
 43             tail = tail->next;
 44             mir[i] = tail;
 45             ptr = ptr->next;
 46         }
 47         
 48         RandomListNode *p1, *p2;
 49         
 50         p1 = head;
 51         p2 = root->next;
 52         while(p1 != NULL){
 53             if(p1->random != NULL){
 54                 p2->random = mir[mri[p1->random]];
 55             }
 56             p1 = p1->next;
 57             p2 = p2->next;
 58         }
 59         
 60         head = root->next;
 61         delete root;
 62         mir.clear();
 63         mri.clear();
 64         
 65         return head;
 66     }
 67 
 68     RandomListNode *deleteList(RandomListNode *head) {
 69         RandomListNode *ptr1, *ptr2;
 70 
 71         if (NULL == head) {
 72             return NULL;
 73         }
 74 
 75         ptr1 = head;
 76         while (ptr1 != NULL) {
 77             ptr2 = ptr1->next;
 78             delete ptr1;
 79             ptr1 = ptr2;
 80         }
 81 
 82         return NULL;
 83     }
 84 private:
 85     map<RandomListNode *, int> mri;
 86     map<int, RandomListNode *> mir;
 87 };
 88 
 89 int main()
 90 {
 91     map<RandomListNode *, int> mri;
 92     map<int, RandomListNode *> mir;
 93     int n, i;
 94     int label;
 95     RandomListNode *head1, *head2, *tail, *ptr;
 96     Solution solution;
 97 
 98     while (scanf("%d", &n) == 1) {
 99         mri.clear();
100         mir.clear();
101         head1 = head2 = tail = NULL;
102         for (i = 1; i <= n; ++i) {
103             scanf("%d", &label);
104             if (tail == NULL) {
105                 head1 = tail = new RandomListNode(label);
106             } else {
107                 tail->next = new RandomListNode(label);
108                 tail = tail->next;
109             }
110             mri[tail] = i;
111             mir[i] = tail;
112         }
113 
114         for (i = 1; i <= n; ++i) {
115             scanf("%d", &label);
116             if (label > 0) {
117                 ptr = mir[i];
118                 ptr->random = mir[label];
119             }
120         }
121 
122         head2 = solution.copyRandomList(head1);
123         ptr = head2;
124         while (ptr != NULL) {
125             printf("%d ", ptr->label);
126             if (ptr->random != NULL) {
127                 printf("%d
", ptr->random->label);
128             } else {
129                 printf("0
");
130             }
131             ptr = ptr->next;
132         }
133 
134         head1 = solution.deleteList(head1);
135         head2 = solution.deleteList(head2);
136     }
137 
138     return 0;
139 }
140 /*
141 // 688773    zhuli19901106    1524    Accepted    点击此处查看所有case的执行结果    1024KB    544B    40MS
142 // 201402012022
143 #include <cstdio>
144 #include <vector>
145 using namespace std;
146 
147 int main()
148 {
149     vector<int> va, vb;
150     int n, i;
151     int a, b;
152 
153     while (scanf("%d", &n) == 1) {
154         va.clear();
155         vb.clear();
156         va.push_back(0);
157         vb.push_back(0);
158         for (i = 1; i <= n; ++i) {
159             scanf("%d", &a);
160             va.push_back(a);
161         }
162         for (i = 1; i <= n; ++i) {
163             scanf("%d", &b);
164             vb.push_back(b);
165         }
166         for (i = 1; i <= n; ++i) {
167             printf("%d %d
", va[i], va[vb[i]]);
168         }
169     }
170 
171     return 0;
172 }
173 */
原文地址:https://www.cnblogs.com/zhuli19901106/p/3539132.html