您的位置:首页 > Web前端

剑指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;
}
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: