剑指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
//
#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 = ;
RandomListNode *ptr; mri.clear();
mir.clear(); ptr = head;
while(ptr != NULL){
++n;
mri[ptr] = n;
ptr = ptr->next;
} RandomListNode *root = new RandomListNode(), *tail;
ptr = head;
int i = ;
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) == ) {
mri.clear();
mir.clear();
head1 = head2 = tail = NULL;
for (i = ; 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 = ; i <= n; ++i) {
scanf("%d", &label);
if (label > ) {
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 ;
}
/*
// 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 - 九度1524 - 复杂链表的复制的更多相关文章

  1. 剑指Offer - 九度1518 - 反转链表

    剑指Offer - 九度1518 - 反转链表2013-11-30 03:09 题目描述: 输入一个链表,反转链表后,输出链表的所有元素.(hint : 请务必使用链表) 输入: 输入可能包含多个测试 ...

  2. 剑指Offer - 九度1519 - 合并两个排序的链表

    剑指Offer - 九度1519 - 合并两个排序的链表2013-11-30 22:04 题目描述: 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则.(hi ...

  3. 剑指Offer - 九度1517 - 链表中倒数第k个结点

    剑指Offer - 九度1517 - 链表中倒数第k个结点2013-11-30 02:57 题目描述: 输入一个链表,输出该链表中倒数第k个结点.(hint: 请务必使用链表.) 输入: 输入可能包含 ...

  4. 剑指Offer - 九度1511 - 从尾到头打印链表

    剑指Offer - 九度1511 - 从尾到头打印链表2013-11-29 21:08 题目描述: 输入一个链表,从尾到头打印链表每个节点的值. 输入: 每个输入文件仅包含一组测试样例.每一组测试案例 ...

  5. 剑指Offer - 九度1505 - 两个链表的第一个公共结点

    剑指Offer - 九度1505 - 两个链表的第一个公共结点2013-11-24 20:09 题目描述: 输入两个链表,找出它们的第一个公共结点. 输入: 输入可能包含多个测试样例.对于每个测试案例 ...

  6. 剑指Offer - 九度1503 - 二叉搜索树与双向链表

    剑指Offer - 九度1503 - 二叉搜索树与双向链表2014-02-05 23:39 题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树 ...

  7. 剑指Offer - 九度1509 - 树中两个结点的最低公共祖先

    剑指Offer - 九度1509 - 树中两个结点的最低公共祖先2014-02-07 01:04 题目描述: 给定一棵树,同时给出树中的两个结点,求它们的最低公共祖先. 输入: 输入可能包含多个测试样 ...

  8. 剑指Offer - 九度1508 - 把字符串转换成整数

    剑指Offer - 九度1508 - 把字符串转换成整数2014-02-06 23:46 题目描述: 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数. 输入: 输入可能包含多个测试样例 ...

  9. 剑指Offer - 九度1504 - 把数组排成最小的数

    剑指Offer - 九度1504 - 把数组排成最小的数2014-02-06 00:19 题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输 ...

随机推荐

  1. des的根据key进行加密和解密方法

    DES加密: public static string DESEncode(string content, string key) { DESCryptoServiceProvider des = n ...

  2. Mac安装protobuf 流程

    下载 https://github.com/google/protobuf/releases 找到对应版本下载 编译 cd protobuf./autogen.sh./configuremake 安装 ...

  3. webpack-dev-middleware插件的使用

    我们在使用webpack 编译文件时,每次改动文件都要去重新编译,是不是很麻烦,这时候我们就用到了webpack-dev-middleware 插件,该插件对更改的文件进行监控,编译, 一般和 web ...

  4. SpringBoot发布WAR启动报错:Error assembling WAR: webxml attribute is required

    Spring Boot发布war包流程: 1.修改web model的pom.xml <packaging>war</packaging> SpringBoot默认发布的都是j ...

  5. System.Web.UI.HtmlControls

    用来创建一个标签.HtmlContainerControl 一般用此类来新建标签. 可能我们熟悉System.Web.UI.WebControls;空间.System.Web.UI.WebContro ...

  6. CSS-DOM

    在所有的产品设计中,选择最适用的工具去解决问题是最基本的原则. ①使用(X)HTML去搭建文档的结构. ②使用CSS 去设置文档的呈现效果. ③使用DOM脚本去实现文档的行为. 文档中的每个元素都是一 ...

  7. JavaWeb —— JSP 总结

      JSP总结 静态网页 在网站设计中,纯粹HTML(标准通用标记语言下的一个应用)格式的网页通常被称为“静态网页”,静态网页是标准的HTML文件,它的文件扩展名是.htm..html  .静态网页是 ...

  8. JavaWeb-拦截器,过滤器,监听器的区别和执行顺序

    一:拦截器 :是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,springmvc的aop中的前置通知和后置通知. 二: ...

  9. 使用nsis开发自定义安装包使用心得,以及遇到坑

    因为新公司需要开发pc应用的自定义安装包,开始时候计划使用nsis开发,论坛上面有很多不错的例子,而且完成度很强, 随便拿来修改使用,但是后续的开发过程中遇到的问题就逐个出现. 首先说一下nsis的优 ...

  10. react中实现原生enter/回车事件及antdesign组件实现方式

    先直接上核心代码: this.goToHomePage换成自己逻辑 自己写的时候直接把this.goToHmoPage()换成自己的逻辑就行了,还有注意一点的是: 需要传个空函数,不然会报错 在com ...