《剑指offer》面试题35. 复杂链表的复制
问题描述
请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。
示例 1:
输入:head = [[7,null],[13,0],[11,4],[10,2],[1,0]]
输出:[[7,null],[13,0],[11,4],[10,2],[1,0]]
示例 2:
输入:head = [[1,1],[2,1]]
输出:[[1,1],[2,1]]
示例 3:
输入:head = [[3,null],[3,0],[3,null]]
输出:[[3,null],[3,0],[3,null]]
示例 4:
输入:head = []
输出:[]
解释:给定的链表为空(空指针),因此返回 null。
提示:
-10000 <= Node.val <= 10000
Node.random 为空(null)或指向链表中的节点。
节点数目不超过 1000 。
问题分析
分为以下三个步骤:
- 在原链表的每个节点后面拷贝出一个新的节点。
- 依次给新的节点的随机指针赋值,而且这个赋值非常容易 cur->next->random = cur->random->next。
- 断开链表可得到深度拷贝后的新链表。
举个例子来说吧,比如原链表是 1(NULL) -> 2(1) -> 3(NULL) -> 4(3),括号中是其 random 指针指向的结点,那么这个解法是首先比遍历一遍原链表,在每个结点后拷贝一个同样的结点,但是拷贝结点的 random 指针仍为空,则原链表变为 1(NULL) -> 1(null) -> 2(1) -> 2(null) -> 3(NULL) -> 3(NULL) -> 4(2) ->4(NULL)。然后第二次遍历,是将拷贝结点的 random 指针赋上正确的值,则原链表变为 1(NULL) -> 1(NULL) -> 2(1) -> 2(1) -> 3(NULL) -> 3(NULL) -> 4(2) -> 4(2),注意赋值语句为:cur->next->random = cur->random->next;这里的 cur 是原链表中结点,cur->next 则为拷贝链表的结点,cur->next->random 则为拷贝链表的 random 指针。cur->random 为原链表结点的 random 指针指向的结点,因为其指向的还是原链表的结点,所以我们要再加个 next,才能指向拷贝链表的结点。最后再遍历一次,就是要把原链表和拷贝链表断开即可
代码
/*
// Definition for a Node.
class Node {
public:
int val;
Node* next;
Node* random;
Node(int _val) {
val = _val;
next = NULL;
random = NULL;
}
};
*/
class Solution {
public:
Node* copyRandomList(Node* head) {
if(!head)return NULL;
Node* cur = head;
//将每个链表的节点后面都拷贝一个相同数值的节点,但拷贝节点的random为空
while(cur)
{
Node* t = new Node(cur->val);
t->next = cur->next;
cur->next = t;
cur = t->next;
}
cur = head;
//对拷贝节点的random进行赋值
while(cur)
{
if(cur->random)
cur->next->random = cur->random->next;//实际上指向的是cur->random,这个是由cur->random拷贝出来的那一个
cur = cur->next->next;
}
cur = head;
//将拷贝的节点分离出来
Node* ans = cur->next;
Node* t = ans;
while(cur)
{
cur->next = cur->next->next;
cur = cur->next;
if(t->next)
{
t->next = t->next->next;
t = t->next;
}
}
return ans;
}
};
结果
执行用时 :16 ms, 在所有 C++ 提交中击败了65.68%的用户
内存消耗 :11 MB, 在所有 C++ 提交中击败了100.00%的用户
当然还有递归和哈希表的解法,后面补充。
《剑指offer》面试题35. 复杂链表的复制的更多相关文章
- 剑指offer 面试题35.复杂链表的复制
时间O(N),空间O(N) /* struct RandomListNode { int label; struct RandomListNode *next, *random; RandomList ...
- 剑指offer面试题26-复杂链表的复制
题目: 请实现函数ComplexListNode* Clone(ComplexListNode* pHead).复制一个复杂链表. 在复杂链表中.每个节点除了一个m_pNext指针指向下一个节点外,另 ...
- 剑指Offer - 九度1524 - 复杂链表的复制
剑指Offer - 九度1524 - 复杂链表的复制2014-02-07 01:30 题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点 ...
- 剑指Offer面试题:14.链表的倒数第k个节点
PS:这是一道出境率极高的题目,记得去年参加校园招聘时我看到了3次,但是每次写的都不完善. 一.题目:链表的倒数第k个节点 题目:输入一个链表,输出该链表中倒数第k个结点.为了符合大多数人的习惯,本题 ...
- C++版 - 剑指Offer 面试题35:第一个只出现一次的字符 解题报告(华为OJ034-找出字符串中第一个只出现一次的字符)
面试题35:第一个只出现一次的字符 题目:在一个字符串中找到第一个只出现一次的字符.如输入abaccdeff,则输出b.(2006年google的一道笔试题.) 分析: 首先应向确认一下是ASCII字 ...
- 剑指Offer:面试题16——反转链表(java实现)
问题描述 定义一个函数,输入一个链表的头结点,反转该链表并输出反转后的链表的头结点.链表结点如下: public class ListNode { int val; ListNode next = n ...
- 【剑指offer 面试题15】链表中倒数第K个结点
思路: 定义两个指针同时指向head,第一个指针先走K-1步,随后二个指针同时移动,当第一个指针到末尾处时,第二个指针所指向的即为倒数第K个结点. #include <iostream> ...
- 剑指offer面试题15:链表中倒数第K个节点
题目:输入一个链表,输出该链表的倒数第K个节点.为了符合大多数人的习惯,本题从1开始计数,即链表尾节点是倒数第一个节点. 解题思路: 解法一:一般情况下,单向链表无法从后一个节点获取到它前面的节点,可 ...
- 剑指offer——面试题23:链表中环的入口节点
函数: ListNode* MeetingNode(ListNode* pHead) { if(pHead==nullptr) return nullptr; ListNode* quickNode= ...
- 剑指offer——面试题18:删除链表的节点
#include"List.h" void DeleteNode(ListNode** pHead,ListNode* pToBeDeleted) { if(*pHead==nul ...
随机推荐
- Spring5 概述及Spring IOC学习
Spring Framework 5 1. Spring框架 1.1 Spring框架概述 1.2 主要内容 Spring框架是一个开源的JavaEE的应用程序 主要核心是 IOC(控制反转)和AOP ...
- LuoguP7892 『JROI-3』R.I.P. 题解
Update \(\texttt{2021.10.11}\) 修改了一处公式错误,麻烦管理重新审核一下这篇已审核通过文章. Content 你在一个无限大的格子平面上,并且有 \(m\) 个长度为 \ ...
- 请注意JS方法,方法同名,参数个数不一样是不能区分方法的,
请注意JS方法,方法同名,参数个数不一样是不能区分方法的, 所以要区分方法,只能利用方法名不同来区分,而不能利用参数个数与参数类型来分.
- windows使用natapp教程
这种免费的 有个缺点 过段时间就会连接不上,需要不定时更换域名地址 Linux系统参考:https://www.cnblogs.com/pxblog/p/10549847.html 官网地址:http ...
- office2007(word2007)另存为pdf文档
默认office2007(word2007)是没有另存为pdf文档的功能的,需要安装插件 插件地址:https://yvioo.lanzous.com/iO5myedoceh 下载之后直接安装,安装成 ...
- 【LeetCode】448. Find All Numbers Disappeared in an Array 解题报告(Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 方法一:暴力求解 方法二:原地变负做标记 方法三:使用set ...
- 【九度OJ】题目1191:矩阵最大值 解题报告
[九度OJ]题目1191:矩阵最大值 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1191 题目描述: 编写一个程序输入一个mXn的 ...
- 【LeetCode】537. Complex Number Multiplication 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 解题方法 日期 题目地址:https://leetcode.com/pr ...
- 【LeetCode】677. Map Sum Pairs 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 字典 前缀树 日期 题目地址:https://lee ...
- Codeforces 876B:Divisiblity of Differences(数学)
B. Divisiblity of Differences You are given a multiset of n integers. You should select exactly k of ...