力扣138. 复制带随机指针的链表(迭代、原地复制切割)
https://leetcode-cn.com/problems/copy-list-with-random-pointer/
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。
要求返回这个链表的 深拷贝。
我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:
val:一个表示 Node.val 的整数。
random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为 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 。
复杂度分析
#include "stdafx.h"
#include
using namespace std;
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 == nullptr)return nullptr;
//哑结点没处理好,后面懒得搞了,直接特例吧
if (head->next == nullptr)
{
Node* one = new Node(head->val);
one->next = nullptr;
head->random == nullptr ? one->random = nullptr : one->random = one;
return one;
}
//先原地复制val和next
Node* yuan = head;
while (yuan != nullptr)
{
Node* temp = new Node(yuan->val);
temp->next = yuan->next;
yuan->next = temp;
yuan = yuan->next->next;
}
//再复制randon指针
Node* p = head;
Node* q = p->next;
while (true)
{
if (p->random == nullptr)
{
q->random == nullptr;
}
else
{
q->random = p->random->next;
cout << "旧的随机指针值:" << p->random->val << '\t' << "新的随机指针值:" << q->random->val << '\n';
}
p = p->next->next;
if (p == nullptr)break;
q = q->next->next;
}
//切割复制的节点
Node* newhead = new Node(0);
newhead->next = head->next;
p = head;
q = head->next;
while (true)
{
p->next = p->next->next;
p = p->next;
q->next = q->next->next;
q = q->next;
if (q->next == nullptr)
{
p->next = nullptr;
break;
}
}
return newhead->next;
}
};
int main()
{
Node head[5] = { 7,13,11,10,1 };
head[0].next = &head[1];
head[1].next = &head[2]; head[1].random = &head[0];
head[2].next = &head[3]; head[2].random = &head[4];
head[3].next = &head[4]; head[3].random = &head[2];
head[4].random = &head[0];
Node* out0 = head;
while (out0)
{
cout << out0->val << '\t';
out0 = out0->next;
}
cout << '\n';
Solution s;
auto result = s.copyRandomList(head);
Node* out1 = result;
while (out1)
{
cout << out1->val << '\t';
out1 = out1->next;
}
cout << '\n';
return 0;
}