力扣138. 复制带随机指针的链表(迭代、原地复制切割)

力扣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 。

 

在原链表的主线上复制节点,进行删改操作。

复杂度分析

  • 时间复杂度:O(N)
  • 空间复杂度:O(1)

先原地复制val和next

再复制randon指针

力扣138. 复制带随机指针的链表(迭代、原地复制切割)_第1张图片

切割复制的节点

力扣138. 复制带随机指针的链表(迭代、原地复制切割)_第2张图片

#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;
}

 

你可能感兴趣的:(力扣刷题)