LeetCode(138) Copy List with Random Pointer
题目
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null.
Return a deep copy of the list.
分析
实现一个链表的深拷贝,返回拷贝后的新链表。
若是普通链表,逐个拷贝原始链表节点并连接即可,只需O(n)的时间复杂度;但是此题特殊的是,每个节点都有一个random域可以指向该链表中的任何一个节点,所以直接复制无法处理random域,因为其指向的节点很有可能还没有创建出来。
有两种方法处理:
方法一:暴力解决,首先不处理random域,将原始链表复制一份,然后遍历每个原始链表节点,查找其random域,将新链表的对应节点链接,该方法需要O(n^2)的时间复杂度,给出的结果是TLE。
方法二:充分利用原始链表的信息,不用保存原始链表的映射关系,构建新节点时,指针做如下变化,即把新节点插入到相应的旧节点后面(参考):
同理分两步
1、构建新节点random指针:
new1->random = old1->random->next, new2-random = NULL,
new3-random = NULL, new4->random = old4->random->next
2、恢复原始链表以及构建新链表:
old1->next = old1->next->next, new1->next = new1->next->next
该算法时间复杂度O(N),空间复杂度O(1)
AC代码
class Solution {
public:
//方法一:直接复制,再修改random指针
RandomListNode *copyRandomList1(RandomListNode *head) {
if (!head)
return NULL;
RandomListNode *ret = new RandomListNode(head->label), *q = ret;
RandomListNode *p = head->next;
while (p)
{
RandomListNode *tmp = new RandomListNode(p->label);
q->next = tmp;
q = q->next;
p = p->next;
}//while
q->next = NULL;
//处理原始链表的random指针
p = head, q = ret;
RandomListNode *idx1 = head, *idx2 = ret;
while (p)
{
if (p->random == NULL)
q->random = NULL;
else{
idx1 = head;
idx2 = ret;
while (p->random->label != idx1->label)
{
idx1 = idx1->next;
idx2 = idx2->next;
}//while
q->random = idx2;
}//else
p = p->next;
q = q->next;
}//while
return ret;
}
//方法二:充分利用原始链表信息,在每个节点后复制添加
RandomListNode *copyRandomList(RandomListNode *head) {
if (!head)
return NULL;
//首先,复制原始的节点,连接自身后面
RandomListNode *p = head;
while (p)
{
RandomListNode *tmp = new RandomListNode(p->label);
//保存后续节点
RandomListNode *r = p->next;
tmp->next = r;
p->next = tmp;
p = r;
}//while
//然后,将添加的节点random 链接到原始节点random的下一个位置
p = head;
while (p)
{
RandomListNode *q = p->next;
if (p->random == NULL)
q->random = NULL;
else{
q->random = p->random->next;
}//else
//处理下一个原始节点
p = q->next;
}//while
//最后,恢复原始链表,得到新链表
RandomListNode *ret = head->next;
p = head;
RandomListNode *q = head->next;
while (q->next)
{
p->next = q->next;
p = q;
if (q->next)
q = q->next;
}
p->next = NULL;
q->next = NULL;
return ret;
}
};
LeetCode(138) Copy List with Random Pointer的更多相关文章
- 133. Clone Graph 138. Copy List with Random Pointer 拷贝图和链表
133. Clone Graph Clone an undirected graph. Each node in the graph contains a label and a list of it ...
- 【LeetCode练习题】Copy List with Random Pointer
Copy List with Random Pointer A linked list is given such that each node contains an additional rand ...
- [Leetcode Week17]Copy List with Random Pointer
Copy List with Random Pointer 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/copy-list-with-random- ...
- LeetCode(275)H-Index II
题目 Follow up for H-Index: What if the citations array is sorted in ascending order? Could you optimi ...
- LeetCode(220) Contains Duplicate III
题目 Given an array of integers, find out whether there are two distinct indices i and j in the array ...
- LeetCode(154) Find Minimum in Rotated Sorted Array II
题目 Follow up for "Find Minimum in Rotated Sorted Array": What if duplicates are allowed? W ...
- LeetCode(122) Best Time to Buy and Sell Stock II
题目 Say you have an array for which the ith element is the price of a given stock on day i. Design an ...
- LeetCode(116) Populating Next Right Pointers in Each Node
题目 Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode * ...
- LeetCode(113) Path Sum II
题目 Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given ...
随机推荐
- java preparement
1.建立链接 Connection conn = getDataSource().getConnection(); PreparedStatement ps = null; 2不自动 Commit 不 ...
- c++11 thread的学习
http://www.cnblogs.com/wxquare/p/6736202.html 还没开始 留个链接 使用c++11 thread支持实现 一个生产者消费者模型 下面是一个生产者消费者问题 ...
- kali linux安装搜狗输入法
1. 更新软件源 vi /etc/apt/sources.list 2. 安装fcitx apt-get install fcitx 3. 下载deb包到指定目录, dpkg -i sogou**** ...
- es6新语法系列,查找字符串,模板字符串
一.模板字符串: ES6引入了一种新型的字符串字面量语法,我们称之为模板字符串(template strings).除了使用反撇号字符 ` 代替普通字符串的引号 ' 或 " 外,它们看起来与 ...
- 如何检查linux 下是否安装java(jdk)环境
大家可通过下面五条命令来查看linux 系统是否安装了java 环境 1.java -version 2.which java 3.rpm -qa |grep java 4.echo $PATH 5. ...
- 判断JS数据类型的几种方法
原文转自http://www.cnblogs.com/onepixel/p/5126046.html! 说到数据类型,我们先说一下JavaScript 中常见的几种数据类型: 基本类型:string, ...
- 关于纠正《Hive权威指南》中的结论~“hive在使用set自定义变量时,hivevar命名空间是可选的”~的论证
背景: 根据<Hive权威指南>上讲,在hive-0.8.0以后可以使用--define key=value命令定义用户自定义的变量以便在Hive脚本中引用.当用户使用这个功能时,Hive ...
- vue2.X版本vue-cli生成项目后运行失败,报错信息为getaddrinfo ENOTFOUND localhost
问题: 1.使用vue-cli生成项目 2.npm install 3.npm run dev,报错信息如下 解决方法: 经查,发现package.json中dev的脚本变成了"webpac ...
- POJ 2288 Islands and Bridges (状压DP,变形)
题意: 给一个无向图,n个点m条边,每个点有点权,要求找到一条哈密顿路径,使得该路径的f(path)值最大.输出f值,若有多条最大f值的路径,输出路径数量. f值由如下3点累加而来: (1)所有点权之 ...
- UVA 1608 Non-boring sequence 不无聊的序列(分治,中途相遇)
题意:给你一个长度为n序列,如果这个任意连续子序列的中都有至少出现一次的元素,那么就称这个序列是不无聊的,判断这个序列是不是无聊的. 先预处理出每个元素之前和之后相同元素出现的位置,就可以在O(1)的 ...