C++学习记录——链表—(复制随机指针问题)

文章目录

  • 题目
  • 一、利用hash_map函数解决
  • 二、进阶解法
  • 总结
  • 参考文章:


题目

提示:这里可以添加本文要记录的大概内容:

RandomListNode类中的val是节点值,next指针和正常的单链表指针中的next指针的意义一样,都指向下一个节点,rand指针是RandomListNode类中的新增的指针,这个指针可能指向链表中的任意一个节点,也可能指向NULL。

给定一个由RandomListNode节点类型组成的无环单链表的头节点pHead,请实现一个函数完成这个链表中所有结构的复制,并返回复制的新链表的头节点。

结构体如下:

typedef struct Node
{
public:
	int val;
	Node* next;
	Node* rand;
	Node(int data):
		val(data),next(nullptr),rand(nullptr) {}
};

一、利用hash_map函数解决

该方法利用hash_map的STL容器进行快速的解决,其时间复杂度为O(N),空间复杂度为O(N),主要适用于笔试题当中,可以简单有效的解决该问题,以下是算法部分:

//打印部分链表部分
void printARR1(Node* arr)
{
	Node* Arr = arr;
	cout << "开始打印:" << endl;
	cout << "val" << endl;
	while (arr != nullptr)
	{
		cout << arr->val
			<< "->";
		arr = arr->next;
	}
	cout << endl;
	
	cout << "rand" << endl;
	while (Arr != nullptr)
	{
		cout << Arr->rand->val
			<< "->";
		Arr = Arr->next;
	}
}
Node* copyRandom(struct Node* head)
	{
		hash_map<Node*, Node* > temp;//注意要包含头文件
		Node* p = head;
		while (p != nullptr)
		{
			Node* q = new Node(p->val);
			temp[p] = q;
			p = p->next;
		}

		p = head;
		while (p != nullptr)
		{
			temp[p]->next = temp[p->next];
			temp[p]->rand = temp[p->rand];
			p = p->next;
		}
		return temp[head];
	}

不懂hash_map容器的自行在csdn中进行搜索查看该容器,本处不再赘述。
注:在导入hash_map库函数时可能出现如下报错:
C++学习记录——链表—(复制随机指针问题)_第1张图片此时,只需在预处理器中添加:_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS。
C++学习记录——链表—(复制随机指针问题)_第2张图片

二、进阶解法

该方法主要适合在面试时进行回答,其可以不适用额外的数据结构便可以完成链表的复制过程。其思想结构如下图:
C++学习记录——链表—(复制随机指针问题)_第3张图片利用在原链表节点的后一个位置上进行复制的操作,来实现经由链表的结构,便可以实现完整的复制功能。
算法代码如下:

Node* copyRandom1(Node* head)
{
	Node* temp = nullptr; //用于临时存储
	Node* p = head;//用于进行复制;
	//先复制节点
	while (p != nullptr)
	{
		temp = p->next;
		p->next = new Node(p->val);//进行复制
		p->next->next = temp;
		p = temp;
	}
	//复制rand节点
	p = head;
	Node* copy;
	while (p != nullptr)
	{
		temp = p->next->next;//确保全都指向p上
		copy = p->next;//指向复制的节点上
		copy->rand = p->rand != nullptr ? p->rand->next : nullptr; //判断rand节点是否指向空
		//,若不为空则指向原链表的随机节点,然后在指向该节点的下一个即复制下的该节点
		p = temp;
	}
	Node* de = head->next;
	p = head;
	//分离
	while (p != nullptr)
	{
		temp = p->next->next;
		copy = p->next;
		p->next = temp;
		copy->next = temp != nullptr ? temp->next : nullptr;//防止temp指向最后一个原链表节点时为空的情况
		p = temp;
	}
	return de;
}

总结

以上便是对于含随机链表题的两种不同的解法。

参考文章:

左程云著《程序员代码面试指南》。

你可能感兴趣的:(C++(算法学习),c++,c语言)