Leetcode学习之链表(4)

开宗明义:本系列基于小象学院林沐老师课程《面试算法 LeetCode 刷题班》,刷题小白,旨在理解和交流,重在记录,望各位大牛指点!


Leetcode学习之链表(4)



1、链表划分 Leetcode 86.

题目来源: L e e t c o d e   86.   P a r t i t i o n   L i s t Leetcode \ 86. \ Partition \ List
题目描述:已知链表头指针 h e a d head 与数值 x ,将所有小于x的节点放在大于或者等于x的节点前,且保持这些节点的原来的相对位置
要求描述:
在这里插入图片描述
思路①
使用临时头节点,也就是两个节点,一个 l e s s h e a d less-head 放小于 x x 的,一个 m o r e p t r more-ptr 存放大于等于 x x 的节点。
在这里插入图片描述
测试代码:

#include <stdio.h>
#include <set>
using namespace std;

struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x) :val(x), next(NULL) {}
};

class Solution {
public:
	ListNode *partition(ListNode *head,int x) {
		ListNode less_head(0);//设置两个临时的头节点
		ListNode more_head(0);
		ListNode *less_ptr = &less_head;
		ListNode *more_ptr = &more_head;//对应指针指向这两个头节点
		while (head){
			if (head->val < x) {
				less_ptr->next = head;
				less_ptr = head;//连接完成后,将less_ptr对应向后移动
			}
			else {
				more_ptr->next = head;
				more_ptr = head;
			}
			head = head->next;
		}
		less_ptr->next = more_head.next;//这边将less的链接尾,与more链表头相连,注意这里是more_head,而不是more_ptr
		more_ptr->next = NULL;
		return less_head.next;//这边注意这里是less_head,而不是less_ptr
	}
};

int main()
{
	ListNode a(1),b(4),c(3),d(2),e(5),f(2);
	a.next = &b;
	b.next = &c;
	c.next = &d;
	d.next = &e;
	e.next = &f;
	Solution solve;
	ListNode *node = solve.partition(&a,3);
	while (node)
	{
		printf("%d\n", node->val);
		node = node->next;
	}
	system("pause");
	return 0;
}

效果图:
在这里插入图片描述


2、STL Map

M a p Map 是一个映射,它用于储存数据并且能从一个数据集合中取出数据。它的数据组成包含两项,一个是它的数据值,一个是用于排序的关键字。其中关键字是唯一的,它用于将数据自动排序。而每个元素的数据值与关键字无关,可以直接改变。简单的说自动建立 K e y v a l u e Key - value 的对应。 k e y key v a l u e value 可以是任意你需要的类型。根据 k e y key 值快速查找记录,查找的复杂度基本是 L o g ( N ) Log(N) ,如果有1000个记录,最多查找10次,1,000,000个记录,最多查找20次

#include <stdio.h>
#include <map>
using namespace std;

struct RandomListNode {
	int label;
	RandomListNode *next, *random;
	RandomListNode(int x) :label(x), next(NULL), random(NULL) {}  //构造函数
};

int main() {
	map<RandomListNode * , int> node_map;//构造map 定义了一个用指针作为索引,并拥有相关联的int类型的值.
	RandomListNode a(5), b(3), c(6);//设置宇哥节点map,key为节点地址,value为整型
	a.next = &b;
	b.next = &c;
	a.random = &c;
	b.random = &a;
	c.random = &c;
	node_map[&a] = 1;//改变map中的key
	node_map[&b] = 2;//地址到节点id的映射,也就是根据地址来查找节点id
	node_map[&c] = 3;
	printf("a.random id = %d\n",node_map[a.random]);
	printf("b.random id = %d\n", node_map[b.random]);
	printf("c.random id = %d\n", node_map[c.random]);
	system("pause");
	return 0;
}

效果图
在这里插入图片描述


3、复杂链表的深度拷贝 Leetcode 138.

题目来源: L e e t c o d e   138.   C o p y   L i s t   w i t h   R a n d o m   P o i n t e r Leetcode \ 138.\ Copy \ List \ with \ Random \ Pointer
题目描述:已知一个复杂的链表,节点中有一个指向本链表任意某个节点的随机指针(也可以为空),求这个链表的深度拷贝
。其中深度拷贝:构造生成一个完全新的链表,即使原链表毁坏,新链表也独立可用
在这里插入图片描述
首先介绍一下浅拷贝深拷贝

浅拷贝只是对指针的拷贝,拷贝后两个指针指向同一个内存空间,深拷贝不但对指针进行拷贝,而且对指针指向的内容进行拷贝,经深拷贝后的指针和原指针是指向两个不同地址的指针。

思路节点地址 与 节点序号 对应
在这里插入图片描述

测试代码:

#include <stdio.h>
#include <map>
#include <vector>
using namespace std;

struct RandomListNode {
	int label;
	RandomListNode *next, *random; //带有随机指针的链表节点
	RandomListNode(int x) :label(x), next(NULL), random(NULL) {}  //构造函数
};

class Solution {
public:
	RandomListNode *copyRandomList(RandomListNode *head) {
		map<RandomListNode *, int> node_map;//原始链表地址到节点的映射,也就是根据地址的值来查找节点id,这边很重要哦!
		vector<RandomListNode *> node_vec;//使用vector根据存储节点位置访问地址,新链表的第几号的地址是什么
		RandomListNode *ptr = head;//记录链表的头位置
		int i = 0;//表示遍历到原始链表的第几号
		//
		while (ptr)//将新链表节点push入node_vec,生成了新链表节点位置到地址的映射
		{
			node_vec.push_back(new RandomListNode(ptr->label));//节点
			node_map[ptr] = i;//记录原始链表地址对节点位置的映射
			ptr = ptr->next;//遍历原始列表
			i++;//记录节点位置
		}
		node_vec.push_back(0);//操作为了一致
		ptr = head;
		i = 0;
		while (ptr)//遍历第二次
		{
			node_vec[i]->next = node_vec[i + 1];//连接新链表next指针,这边仔细思考!
			if (ptr->random) {//当random不为空时
				int id = node_map[ptr->random];//根据node_map确认原链表random指针指向的位置,即id
				node_vec[i]->random = node_vec[id];//连接新链表的random指针,node_vec[id]新节点的各个地址
			}
			ptr = ptr->next;
			i++;
		}
		return node_vec[0];
	}
};

int main() {
	RandomListNode a(1), b(2), c(3), d(4), e(5);
	a.next = &b;
	b.next = &c;
	c.next = &d;
	d.next = &e;
	a.random = &c;
	b.random = &d;
	c.random = &c;
	e.random = &d;
	Solution solve;
	RandomListNode *head = solve.copyRandomList(&a);
	while (head)
	{
		printf("label = %d  ",head->label);
		if (head->random)
		{
			printf("rand = %d\n", head->random->label);
		}
		else
		{
			printf("rand = NULL\n");
		}
		head = head->next;
	}
	system("pause");
	return 0;
}

效果图:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_33948796/article/details/89715748